デリゲートパターンでは、1つのオブジェクトのみが別のオブジェクトのイベントを直接リッスンできます。 observer patternでは、任意の数のオブジェクトが特定のオブジェクトのイベントをリッスンできます。他のオブジェクトにイベントを通知する必要があるクラスを設計するときに、オブザーバーパターンよりもデリゲートパターンを使用するのはなぜですか?オブザーバーパターンはより柔軟であると思います。現在、オブザーバーは1人しかいませんが、将来の設計では複数のオブザーバーが必要になる可能性があります。
デリゲートパターン自体はありません。私はあなたが 委任パターン を意味すると仮定します。
私が理解しているように、これらは互いに完全に逆であり、さまざまな目的で使用されています。
一般に、 Observer Pattern を使用すると、任意の数のオブザーバーオブジェクトが2番目のオブジェクトのイベントをリッスンし、イベントに作用します。 2番目のオブジェクトはリスナーを認識していません。彼らに声をかけるだけです。
デリゲートオブジェクトは、デリゲートで直接メソッドを呼び出す2番目のオブジェクトに渡されます。そしてそこにあなたが探している利点があります。単一のメッセージを複数のリスナーに送信するのではなく、単一のオブジェクトを(特定の時点で)完全に制御します。 Inversion of Control も参照してください。
あなたは物事を間違って見ています。オブザーバーは、特定のイベントが発生したことを確認します。それに影響を与えたり、所有したりすることはありません。デリゲートhandles特定のイベントであり、デリゲーターがイベントへのインターフェースを所有している場合でも、ハンドラーの所有権を持ちます。
それはいくつかのトレードオフの問題です。
トレードオフ:
デリゲートパターン:
オブザーバーパターン:
私が理解しているように、デリゲートパターンは、Delphiなどの他の言語ではイベントハンドラーメカニズムとして知られています。そのため、これは単に、オブザーバーパターンの実装であり、大きな制限があります。一度に1つのリスナーのみです。
イベントハンドラーまたはデリゲートの欠点は明らかです。オブザーバーが1つだけです。
利点はそれほど明白ではありません。パフォーマンスです。オブザーバーパターンを使用すると、多くのオブザーバーを追加できます。オブザーバーに通知する必要があるイベントが発生した場合、オブザーバーを列挙し、それぞれに通知を送信する必要があります。これは、特に通知を必要とするイベントの数が非常に多い場合に、観察されたインスタンスをすぐに停止させる可能性があります。
これは古い投稿ですが、いずれにしても、他の回答ではどちらのパターンを使用した場合にも何が起こっているかを扱っていないので、私はチャイムを鳴らします。
委任とオブザーバーの仕組み
委任を使用すると、委任者は、潜在的なイベントのソースが作成された瞬間に、特定のイベントに誰が応答するかを正確に選択します。このリスナーは単一のobserverと考えることができます。オブザーバーパターンの場合、オブザーバーは、気になるときはいつでも、誰が監視しているかを選択します。したがって、オブザーバーと委任では依存関係が逆になります。オブザーバーパターンでは、新聞と購読者をオブザーバーとして考えます。オブザーバーは、関係が作成されるタイミングを制御します。代表団と一緒に、従業員と雇用者について考えてください。雇用主は、関係が作成される時期と、特定のイベントの担当者を正確に管理します。従業員は自分が取り組んでいるタスクを選ぶことはできません...一般的に。
委任には1人のオブザーバーがいる可能性があると主張する人もいますが、2人の実際の違いは、イベント処理の割り当て方法にあると思います。イベントのデリゲートレジスタは表示されません。イベントが発生し、委任者がイベントに対してパブリックメソッドを呼び出すまで、イベントが処理されることさえわかりません。
委任の利点
このパターンは非常に厳格であり、ほとんどのregidの設計では、より単純で、一般により堅牢です。潜在的なイベントのソースを初期化するときに、イベントハンドラーを事前に宣言する必要があります。誰かに交通を誘導する必要がある場合は、通りを開く前に交通ディレクターを割り当てます。オブザーバーの場合は、交通警官に、トラフィックが気になるときにいつトラフィックを転送するかを選択させます。
委任の欠点
この設計の欠点は、柔軟性がないことです。新聞を購読するためのコードを実装している場合、新聞/委任者は、作成された2番目のニュース記事を誰が読むことができるかを正確に特定する必要があります。オブザーバーパターンを使用すると、後でいつでも登録でき、新聞は新しい人物が登録したことを知るだけで済みます。
委任を選択するタイミング?
特定のオブザーバーが確実に必要で、誰を監視するかを変更する理由がない場合は、委任パターンの厳密な設計が有益です。
たとえば、特定のエラーのポップアップの作成を処理するクラス/オブジェクトが必要です。実行時に特定のエラーを処理するユーザーを切り替える必要がある理由は多くありません。そのため、「メモリ不足」エラーを単一のエンティティに委任することは理にかなっています。潜在的なハンドラーの配列を作成し、それらのハンドラーに「メモリ不足」エラーを登録させることは、あまり意味がありません。これは、この状況でオブザーバーパターンを使用する例です。実行時に、呼び出されるメソッドや変数イベントで呼び出される「デリゲート」を変更したい場合がありますが、実行時に特定のイベントのイベントハンドラーをスワップアウトすることは正常ではありません。
オブザーバーパターンで行うようにデリゲートを交換することは不可能ではなく、複雑です。現実の世界では、新しい委任者がトラフィックを処理するように、トラフィックの警官を入れ替えることができます。より良い設計は、元の代理人を警察署ではなく一人の警察官にするであろうと主張することができますが、私は余談です...