0

什么是最好的设计方法?要求是创建一个执行 20-30 个不同步骤的简单服务接口。换句话说,我有一个带有函数 DoSomeWork() 的服务类。DoSomeWork 将执行 20-30 步,如果成功返回成功消息,如果失败则返回失败位置和原因的确切消息。

public class SomeWork :ISomeWorkWork{
public StatusMessage DoSomeWork(){
   //Do Step 1
   //Do Step 2
   //Do Step 3
 }
}

最简单的方法是将所有步骤封装在私有方法中,并在 DoSomeWork() 方法中调用它们。但这是不可接受的,因为那时各个步骤将不可测试,不可模拟。另一种方法是创建一个单独的类来实现一个接口,比如 ISomeWorkService。然后在 DoSomeWork 方法中通过 IOC 容器获取 ISomeWorkService 的实例并调用步骤的方法。我在想状态模式是否适合这种情况。我需要的是 DoSomeWork 应该能够自动找出它需要执行的步骤,并且它应该运行到最后一步,或者如果遇到任何错误则退出。任何帮助都会很明显:)

4

1 回答 1

1

我不太愿意提出这个建议,因为 20 个步骤需要解决很多问题(事实上,尝试对此做一些事情可能是值得的),所以事情可能会变得一团糟,但是......

您可以采取的一种方法是使用某种委托机制,这将允许调用者中断代码流并覆盖步骤中的默认逻辑。您可以使用事件来实现相同的效果,尽管我认为委托可能会稍微干净一些。

这将允许调用者(可能是单元测试平台)模拟单个步骤。或不。

因此,DoSomeWork() 仍将包含这样的逻辑,即执行第 1 步、现在执行第 2 步、现在执行第 3 步等,但这些步骤本身可以(但不必)被调用者覆盖。

正如我所说,如果你在谈论几十个步骤,这可能会变得非常混乱,但我越想它,我认为你采取的任何允许你模拟这么多步骤的方法都会变得非常混乱。

例如(假设您正在处理小部件并使用委托):

您的“工人”类如下所示:

public delegate Widget StepOneActionDelegate(Widget widget);

public class Worker
{

    public StepOneActionDelegate StepOneAction { get; set; }

    public Worker()
    {
        StepOneAction = RealStepOne;
    }

    public void DoSomeWork()
    {
        Widget widget = new Widget();
        Widget newWidget = StepOneAction(widget);
        // more steps here
    }

    private Widget RealStepOne(Widget widget)
    {
        // Do some real work here
        return widget;
    }
}

...而您的测试工具可以做类似...

    void Test()
    {
        Worker worker = new Worker();
        worker.StepOneAction = NewStepOne;
        worker.DoSomeWork();
    }


    Widget NewStepOne(Widget widget)
    {
        // Do some mocking here
        return widget;
    }

......在“现实生活”中你会说......

    void DoItForReal()
    {
        Worker worker = new Worker();
        worker.DoWork();
    }

如果您愿意,这种方法将允许您单独模拟每个步骤,但在开发时保留 Worker 类的结构/功能。它还可以让您在未来创建更专业的 Worker,例如,可以购买原始 Worker 类的大部分步骤,但可以在步骤 5、9 和 14 中做自己的事情。

于 2013-05-15T07:57:03.917 回答