私はかなり前からコマンドパターンを使用していますが、Execute
メソッドに実際にどれだけのロジックを配置できるかはよくわかりません。
コマンドパターンの現在の実装は次のようになります。
public abstract class Command
{
public static event EventHandler Completed = delegate { };
public bool Success { get; private set; }
public Exception Exception {get; private set; }
public abstract bool Execute();
protected bool OnCompleted(bool success, Exception ex = null)
{
Success = success;
Exception = ex;
Completed(this, EventArgs.Empty)
return success;
}
}
そして、これらは私が自分自身に尋ねる(そして私のコマンドで練習する)質問です:
button1_Click
?コマンドパターンを実装する方法を示すチュートリアルはたくさんありますが、実際のウォルドアプリケーションに適用する方法については実際には説明されていません。
コマンドパターンは、WHATをWHOから切り離し、WHATをWHENから切り離すために一般的に使用されます。これは、次のように単純なインターフェースを持つことの利点です。
public abstract class Command {
public abstract void execute();
}
クラスEngineOnCommand
があるとしましょう。このコマンドを、コマンドのインスタンスを受け入れる他のオブジェクトに渡すことができます。つまり、これは、このEngineOnCommandを受け取るクラスが、別のコマンドを受け取って実行することもでき、それを知ってはならないということです。これは、[〜#〜] what [〜#〜]を[〜#〜] who [から分離したことを意味します〜#〜]。
ここで、コマンドPattermの2番目のケースは、[〜#〜]を[〜#〜]いつ[〜#〜]。データベース内のアクションが夜間にのみ実行され、要求されたシーケンスに従う必要があるシステムを作成するとします。 1つずつ実行できるコマンドのキューを使用すると、これを実現できます。アイデアは、コマンドの呼び出しが実際に後で実行されるリスト上のコマンドのエンキューをトリガーするだけであるということです。
上記の私の例がパターンのアイデアを理解するのに役立つことを願っています。ここで、上記をベースにして、いくつかの質問に答えてみます。
コマンドにビジネスロジックを含めることはできますか?
はい、それはそれを含むべきだと思います。 WHOとWHENの分離された方法で含まれます。
コマンドはとにかくGUIコントロールを変更できますか?
これは、それをGUIに結合していることを意味します。これは、WHOからWHATを分離する目的で使用されていないことを意味します。コマンドがGUIまたはバッチ機能である場合、コマンドは誰がそれを呼び出しているのかを知るべきではありません。
ユニットテスト可能なコマンドである必要がありますか?
それはすべきではありません、それはユニットテスト可能でなければなりません。すべてのコードは単体テスト可能でなければなりませんが、理想的にはすべてのコマンドが単体テスト可能でなければなりません。
すべての質問に答えられなかったのは残念ですが、 [〜#〜] gof [〜#〜] の本を確認してください。良い例がいくつか含まれています。
コマンドの利点のほとんどは、アクションを元に戻したり、やり直したり、複数の場所で(ネットワーク接続を介して)アクションを実行したり、後で実行したりすることが簡単にできることです。
それを念頭に置いて:
おそらく違います。ダイアログボックスを「元に戻す」ことが理にかなっている状況を想像するのは困難です。これは、UIコードに入れたい種類のことです。
コマンドを実行する可能性のあるすべての場所からそのオブジェクトにアクセスできる限り、当然、そのプロパティを変更してもかまいません。
もちろんです。これは、モデルにビジネスロジックを「含める」必要があるかどうかに関係します。ビジネスロジックが少なすぎると、実際にはアンチパターン(「貧血ドメインモデル」)と見なされます。
GUIコントロールがモデルの一部である場合は、絶対です。そうでなければ、それは疑わしいです。
間違いなくビューではありません。データまたはモデルが変更され、それに応じて反応することをビューに通知する必要がありますが、実際の変更はデータまたはモデルで行われる必要があります。
原則として、おそらくはい。コマンドを元に戻すことができることは、パターンの最も優れた点の1つです。
コマンドのexecute()関数は必ずユニットテストする必要があります。繰り返しますが、コマンドが何らかのモデルに関連付けられている場合、それらはアプリケーションのテストが最も容易な部分の1つです。
どういう意味かよくわかりませんが、
もちろんです。コマンドがコードを実行しない場合、コマンドの利点のほとんどは、実装するのがある程度不可能です。
それはおそらく今では明白ですが、それらを相互に排他的であるとはまったく見なしていません。私のチームでは、コントローラーがユーザーが生成したイベントをコマンドに変換し、モデルがコマンドを受け取って実行し(そして「元に戻す」コマンドをどこかに保存します)、完了したら、コントローラーはビューに新しいモデルに基づいて自身を更新するように指示します。コマンドは、ネットワークを介して他のユーザーが表示しているモデルのコピーにも送信されるため、他のユーザーにも表示されます。それは見事に機能します。
そしてタイトルの質問:1つのコマンドにどのくらいのロジックを入れるか?私はそれに最小値または最大値を設定しません。私が言えることは、一連のより単純なコマンドを使用してより複雑なコマンドを実装し、関数をリファクタリングするのと同じ方法でコマンドをリファクタリングすることは非常に良いアイデアだということです。