设计模式场景 - 我应该使用哪个?

时间:2012-07-09 03:21:20

标签: c# design-patterns

我有一个项目的情况,我目前在工作中工作,整个周末让我的思绪焦躁不安。首先,我需要解释一下我的场景,以及我考虑的可能解决方案。

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

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

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

ServiceX由 POST 使用请求正文中的数据专门用于Web请求。

ServiceY被 POST 消耗,其中包含附加到URL的数据(是的......我知道这应该是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请求。我不确定这是否很好地利用了这些模式。我在想一个替代方案可能是使用策略模式并为我可能需要使用的不同Request方法指定策略对象。如下:

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();
      }
}

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

有什么想法?

2 个答案:

答案 0 :(得分:3)

我会同时使用它们。

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

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

答案 1 :(得分:1)

根据您提供的命令和策略示例,Command模式示例看起来就像一个策略,我想这会引导您进入策略。我也会选择策略,但我想补充一点,Command模式比你在示例中包含的更多。你应该问自己一些问题:

  • 这些命令是否需要存储并且应该在以后的某个时间点执行?
  • 是否有一个Invoker需要调用这些命令而不关心Command internals?
  • 您是否希望具有将不同命令组合在一起并执行它们的功能?

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