0

最良の設計アプローチとは? 要件は、20 ~ 30 の異なる手順を実行する単純なサービス インターフェイスを作成することです。つまり、関数 DoSomeWork() を持つサービス クラスがあります。DoSomeWork は 20 ~ 30 のステップを実行し、成功した場合は成功メッセージを返し、失敗した場合は失敗した場所とその理由の正確なメッセージを返します。

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

最も簡単な方法は、すべてのステップをプライベート メソッド内にカプセル化し、それらを DoSomeWork() メソッド内で呼び出すことです。しかし、個々のステップをテストしたりモックしたりできないため、これは受け入れられません。もう 1 つの方法は、ISomeWorkService などのインターフェイスを実装する別のクラスを作成することです。次に、DoSomeWork メソッド内で、IOC コンテナーを介して ISomeWorkService のインスタンスを取得し、ステップのメソッドを呼び出します。状態パターンがこのシナリオに当てはまるかどうかを考えていました。私が必要としているのは、DoSomeWork が自動的にどのステップを実行する必要があるかを判断し、最後のステップまで実行するか、エラーが発生した場合は終了することです。どんな助けもかなりのものです:)

4

1 に答える 1

1

私はこれを提案するのは少し気が進まない.なぜなら 20 のステップは多くのことと闘わなければならないからである.

1 つの方法として、呼び出し元がコード フローに割り込んで、ステップ内の既定のロジックをオーバーライドできるようにする、ある種のデリゲート メカニズムを用意することができます。イベントを使用して同じ効果を達成することもできますが、デリゲートの方が少しきれいかもしれません。

これにより、呼び出し元 (単体テスト リグである可能性があります) は、個々のステップをモックすることができます。か否か。

したがって、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 に答える