5

我目前正在工作的一个项目中遇到一个情况,这让我整个周末都心神不宁。首先,我需要解释我的场景,以及我考虑过的可能解决方案。

我正在编写一个复合 WCF 服务,它将聚合大量外部 API。这些 API 是任意的,它们的存在就是这个解释所需要的。

这些服务可以在整个开发期间添加和删除。我的 WCF 服务应该能够使用多种方法(REST、SOAP 等)来使用这些服务。对于此示例,我将重点关注通过在代码中手动创建请求来与外部 APIS 进行通信。

例如,我们可能有两个 API 的ServiceXServiceY

ServiceX 通过POST使用请求正文中的数据的 Web 请求来使用。

ServiceY 通过POST使用附加到 URL 的数据的 Web 请求来消耗(是的......我知道这应该是一个 GET,但我没有编写外部 API,所以不要告诉我它。)

为了避免冗余、重复的代码,我使用命令模式包装了 Web 请求,并且正在使用工厂来构建请求。

对于 ServiceX,需要对数据进行编码并放入请求正文中,这与 ServiceY 相反,后者需要迭代数据并放置在 Post 字符串中。

我有一个如下的类结构:

public abstract class PostCommandFactory
{
      public ICommand CreateCommand();
}

public class UrlPostCommandFactory:PostCommandFactory
{
      public ICommand CreateCommand()
      {
              //Initialize Command Object Here
      }
}

public class BodyPostCommandFactory:PostCommandFactory
{
      public ICommand CreateCommand()
      {
              //Initialize Command Object Here
      }
}


public interface ICommand
{
      string Invoke();
}

public class UrlPostCommand:ICommand
{
      public string Invoke()
      {
         //Make URL Post Request
      }
}

public class BodyPostCommand:ICommand
{
      public string Invoke()
      {
         //Make Request Body Post Request
      }
}

这使我可以在需要发送数据时将数据绑定到请求的方式清晰地分开,本质上,我还可以添加其他类来处理 GET 请求。我不确定这是否可以很好地利用这些模式。我在想另一种方法可能是使用策略模式并为我可能需要使用的不同请求方法指定策略对象。如下所示:

public class RequestBodyPostStrategy:IPostStrategy
{
      public string Invoke()
      {
          //Make Request Body POST here
      }
}

public class UrlPostStrategy:IPostStrategy
{
      public string Invoke()
      {
          //Make URL POST here
      }
}

public interface IPostStrategy
{
      string Invoke();
}

public class PostContext
{
      pubic List<IPostStrategy> _strategies;
      public IPostStrategy _strategy;
      public PostContext()
      {
           _strategies = new List<IPostStrategy>();
      }

      public void AddStrategy(IPostStrategy strategy)
      {
            _strategies.Add(strategy);
      }


      public void SetStrategy(IPostStrategy strategy)
      {
           _strategy = strategy;
      }

      public void Execute()
      {
           _strategy.Invoke();
      }
}

我开始认为策略模式可能是更清洁的解决方案。

有什么想法吗?

4

2 回答 2

3

我会同时使用。

命令是封装请求和隐藏实现细节的最佳实践。即使您只有一种请求,您也应该使用它,因为它促进了更简洁的代码。从本质上讲,考虑“我的其余代码需要知道的关于如何执行和处理请求的绝对最小值是多少”是一种很好的做法,这将引导您进入命令模式。

策略基本上是在运行时使用一种通用的、一致的方式来配置您的系统来处理操作的某些方面,在这种情况下会生成请求。这也是一个很好的测试实践,因为您可以将策略/请求工厂的测试实现替换为伪造实际连接等。

于 2012-07-09T06:23:28.420 回答
1

根据您给出的命令和策略示例,命令模式示例看起来完全像一个策略,我猜它会引导您进入策略。我也会选择策略,但想补充一点,命令模式比您在示例中包含的更多。你应该问自己以下问题:

  • 这些命令是否需要存储并应在稍后的时间点执行?
  • 是否有一个调用者需要调用这些命令而不关心命令内部?
  • 您是否想要将不同的命令组合在一起并执行它们的功能?

如果是这种情况,那么您应该选择命令模式。

于 2012-07-09T05:29:29.760 回答