1

そのため、任意のクラスで (パターンに基づいて) コマンドを作成するには、そのクラスがレシーバー クラスを認識してコマンドのコンストラクターに渡す必要があります。これにより、クラスが結合されます。コマンド パターンを使用して、2 つのクラス間の間接性を保つ方法はありますか?

私が考えることができる唯一の解決策は次のとおりです。

  • メディエーターを使用しますが、少なくともコマンドが単なるインターフェースであっても、コマンドをクラスに渡す必要があるため、正確にはわかりません
  • ファサードを使用しますが、コマンド呼び出しクラスをファサードに結合します
  • コマンドの代わりにイベント システムを使用しますが、実行時のオーバーヘッドが大きく、コード自体を記述するだけです。
  • 作成パターンを使用してコマンドを何らかの形で作成しますが、それはすべてをそのオブジェクトに結合します

イベント システムに関する私の最大の懸念は、イベント システムでの私の経験から、送信者と受信者がお互いを知らずに対話するために書かなければならないコードの量は非常識であり、まったく実用的ではないということです。イベントでは、少なくとも 1 つの他のクラスを変更する必要があり、通常は複数のクラスを変更する必要があります。これにより、密結合された spegetti コードと同じくらい悪い問題が発生します。また、通常、イベントに応答を送信するためのクラスが必要ですが、これも非常に面倒です。

4

3 に答える 3

4

コマンド パターンは、作成者と受信者を分離することを意図したものではありません。これらのクラスは通常、すでに結合されているか、同じクラスである場合もあります。

コマンド パターンが行うことは、コマンドを実行するクラスから実装を切り離すことです。コマンドが作成されると、UI レイヤーに渡すか、ネットワークを介してリモート クライアントに渡すことができます。実行クラスは、コマンドの実装方法についての知識を必要としません。

于 2012-08-03T01:29:52.607 に答える
1

まず、ファサードを使用しないでください。最初からデザインにファサードを配置する場合は、おそらくデザインを再考する必要があります。ファサードの主な目的は、対話を簡素化するコード(通常はレガシーコード)を隠すことです。新しいコードは、理想的には最初からより単純なインターフェースで設計する必要があります。

あなたの特定の問題についてもっと知ることなく、私はいくつかの提案があります:

  1. 先に進み、イベントシステムを使用してください。C#には、独自のコードをあまり記述せずに利用できる素晴らしいイベントシステムがあります。いくつかのデリゲートを定義し、イベントハンドラーを追加するだけで、ほとんどの方法でそこに到達できます。イベントを送信するメカニズムは抽象化されているため、ほとんどの作業はイベントを相互に接続することです。これまでイベントをあまり使用したことがない場合は、すばやく検索すると、役立つ情報がたくさん得られるはずです。

  2. 実行時にレシーバーを指定します。

    public interface ICommand {
        public void Execute(IReceiver receiver);
    }
    

    これにより、呼び出されたときにレシーバーを動的に変更できます。これにより、Execute()このパターンを使用して、システム全体に動作を渡すことができます。ただし、この時点で、同じ結果を達成するためのより良い方法があります...

  3. オブジェクトではなく、関数を渡します。 C#が再び救いの手を差し伸べ、他のデータ型と同じように関数をシステムに渡すことができます。コマンドをデリゲートとして指定します。

    class MyThing {
        public delegate void Command(IReceiver receiver);
    
        public static void PrintReceiver(IReceiver receiver){
             // print the receiver
        }
    
        public static void ChangeReceiver(IReceiver receiver){
             // change something about the receiver
        }
    }
    

    これにより、後で次のようなことができるようになります。

    IReceiver receiver = someReceiverThatAlreadyExists;
    Command action = someCondition ? MyThing.PrintReceiver : MyThing.ChangeReceiver;
    action(receiver);
    

    これは非常に単純な例ですが、完全なオブジェクトを必要とせずに、コマンドのように動作する動作を実行する方法を示しています。

于 2012-08-03T01:45:46.317 に答える
1

あなたが持つことができます

public interface ICommandHandler<T> where T : ICommand 
{
    void Execute(T command);
}

もちろん、これには、コマンドを発行者から受信者に転送するためのルーティングコードが必要になります。しかし、このルーティングを規則に基づいている場合、それはそれほど難しい1回限りのコードではないはずです。

(私はこれを、コマンドには単一の明確に定義されたコンシューマーが必要であるという考えに基づいています。そうでない場合、これはイベントである可能性があり、関係者がイベントをサブスクライブしているため、少し異なります。彼ら自身)。

于 2012-08-03T02:45:55.063 に答える