寻找命令模式替代方案

时间:2010-11-18 23:23:38

标签: design-patterns command

我编写了一个测试自动化框架。框架围绕对象和动作构建。对象可能是文本框。它的动作可能是set-text,clear,verify-text,verify-enabled等。框架独立于acitons,因此我们可以随着时间的推移添加更多动作,而无需重新构建框架本身。我考虑了两种行动方法。第一种是使用命令模式。在这种情况下,我会有一个看起来像这样的界面:

  

public interface IAction
  {
  void Execute(StringDictionary properties);
  }

问题是我们最终会遇到许多这样的命令类。

  

public class SetTextAction : IAction
  {
  public void Execute(StringDictionary properties)
  {
  }
  }
  
  public class ClearAction : IAction
  {
  public void Execute(StringDictionary properties)
  {
  }
  }
  
  public class VerifyTextAction : IAction
  {
  public void Execute(StringDictionary properties)
  {
  }
  }
  
  public class VerifyEnabledAction : IAction
  {
  public void Execute(StringDictionary properties)
  {
  }
  }

此外,任何共享代码都需要在另一个类中。它似乎增加了代码中的噪声信号比
我提出的替代方法是使用实​​用程序类作为操作的类型和方法。最终看起来像这样:

  

public class TextboxActions
  {
  public static void set-text(StringDictionary properties)
  {
  }
  public static void clear(StringDictionary properties)
  {
  }
  public static void verify-text(StringDictionary properties)
  {
  }
  public static void verify-enabled(StringDictionary properties)
  {
  }
  }

这样做的好处是文本框的代码都在一起。此外,多个操作共有的任何代码都可以位于同一个类中。不幸的是,这种方法要求我使用反射“找到”动作方法。这显然不是类型安全的,并且可能非常耗时。它足够慢,我添加了一个缓存,所以我不必两次找到相同的操作,但这增加了代码的复杂性。

这些解决方案都有效,但它们都具有不良特性。是否有人可以提出这个问题的替代方法?

2 个答案:

答案 0 :(得分:1)

为什么你不能使用代表?也就是说,遵循一流的功能方法。如果你正在考虑制作单独的IAction具体实例,你可能只需要一个具体的函数指针。这样你的代码可以继续看起来像你的最后一个例子,但不能使用反射。

答案 1 :(得分:0)

委托方法是否与此类似?

   public abstract class TestObject
{
    public delegate void TestAction(StringDictionary properties);

    public void AddTestAction(TestAction action)
    {
    }

    public void Execute()
    {
        // foreach test action etc.
    }
}

public class TestTextBox : TestObject
{
    TestTextBox()
    {
        Initialize();
    }

    private void Initialize()
    {
        AddTestAction(new TestObject.TestAction(this.SetText));
        AddTestAction(new TestObject.TestAction(this.Clear));
    }

    public void SetText(StringDictionary properties)
    {
    }

    public void Clear(StringDictionary properties)
    {
    }
}