寻找命令模式替代方案

发布于 2024-10-03 02:33:48 字数 2172 浏览 6 评论 0原文

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

公共接口IAction
<代码>{
void Execute(StringDictionary 属性);
}

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

公共类SetTextAction:IAction
<代码>{
public void Execute(StringDictionary 属性)
<代码>{
<代码>}
<代码>}

公共类ClearAction:IAction
<代码>{
public void Execute(StringDictionary 属性)
<代码>{
<代码>}
<代码>}

公共类VerifyTextAction:IAction
<代码>{
public void Execute(StringDictionary 属性)
<代码>{
<代码>}
<代码>}

公共类VerifyEnabledAction:IAction
<代码>{
public void Execute(StringDictionary 属性)
<代码>{
<代码>}
}

此外,任何共享代码都需要位于另一个类中。它似乎增加了代码中的噪声与信号之比。

我提出的替代方案是使用实用程序类作为操作的类型和方法。最终看起来像这样:

公共类 TextboxActions
<代码>{
public static void set-text(StringDictionary 属性)
<代码>{
<代码>}
public static void clear(StringDictionary 属性)
<代码>{
<代码>}
public static void verify-text(StringDictionary 属性)
<代码>{
<代码>}
public static void verify-enabled(StringDictionary 属性)
<代码>{
<代码>}
}

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

这些解决方案中的任何一个都有效,但它们都具有不良特征。有人可以建议解决这个问题的替代方法吗?

I have written a Test Automation Framework. The framework is build around objects and actions. An object might be a text box. The actions for it might be things like set-text, clear, verify-text, verify-enabled, etc. The framework is independent of the acitons, so we can add more actions over time without having to respin the framework itself. I considered two approaches for the actions. The first was to use the command pattern. In this case I would have an interface that looks something like this:

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

The issue is that we would end up with many of these command classes.

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)
{
}
}

Furthermore any shared code will need to be in yet another class. It seems to increase the noise to signal ratio in the code.

The alternative I have come up with is to use a utility class for the type and methods for the actions. This ends up looking like this:

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)
{
}
}

This has the advantage that the code for textboxes is all together. In addition, any code that is common to multiple actions can be in the same class. Unfortunately, this approach requires that I use reflection to "find" the action method. This is obviously not type safe and can be time consuming. It is slow enough that I have added a cache so I do not have to find the same action twice, but this adds to the code complexity.

Either of these solutions works, but they both have undesirable characteristics. Is there an alternative approach to this problem that someone can suggest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薔薇婲 2024-10-10 02:33:48

为什么不能使用代表?也就是说,遵循一流的函数方法。如果您正在考虑创建单独的 IAction 具体实例,那么您最好只使用具体的函数指针。这样您的代码可以继续看起来像上一个示例,但不使用反射。

Why can't you use delegates? That is, follow a first-class function approach. If you were thinking of making individual IAction concrete instances, you might as well just have a concrete function pointers instead. That way your code can continue to look like your last example, but not use reflection.

时光沙漏 2024-10-10 02:33:48

委托方法是否与此类似?

   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)
    {
    }
}

The delegate approach would be something along the lines of this?

   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)
    {
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文