どういうわけか、あなたはコンテナを主題に変えなければなりません。
ここでの主な問題は、変更に気付くための効率的な方法を見つけることです。ほとんどの場合、この問題が発生するのは、観察したいものが効率的な通知メカニズムを提供していないためです(おそらく、オブザーバーのデザインパターンが作成時に発明されなかったためです)。
[編集]あなたは効率的な方法を求めているので、一般的な答えは「それは依存する」です。デザインパターンには、「万能」ソリューションはありません。これらは、問題へのアプローチ方法の一般的なルールです。特定の状況でルールを実装する必要がある方法は、その状況にあるときに解決するものです。
一般に、オブザーバーが小さな変更(つまり、属性の変更や要素の追加)を識別する必要がある場合、通知メッセージには、これを効率的に実行できる十分な情報が含まれている必要があります。したがって、大きなリストと挿入がある場合は、新しい要素のリストとインデックスに加えて「挿入されたアイテム」を送信します。
属性の変更に関しては、2つの解決策があります。1つは、リスト内のすべての要素にオブザーバーを追加することです。これは遅く、大量のRAMを必要とする可能性がありますが、同じリストに複数のタイプを追加できることを意味します。
または、「リストサービスのアイテムの変更」を行うこともできます。つまり、アイテムを直接変更することは禁止されており、常にサービスを使用する必要があります。その後、サービスはサブジェクトとして機能し、アイテム、古い値と変更された値、場合によってはリスト内のインデックスを使用して通知を送信できます。
[編集2]原則として、変更に関するできるだけ多くの情報を収集し、それをオブザーバーに渡します。しかし、それは本当にあなたの特定の問題に依存します。オブザーバーがリモートマシンに座っているとしましょう。この場合、リスト全体を送信する効率的な方法はありません。送信できるのは「アイテムXが挿入されました」だけで、それで十分です。コンテナに変更を通知する方法がない場合(たとえば、Webサイトの新しいWebページ)、コンテナはサイト全体を何度もトラバースして変更を見つけ、それをオブザーバーに効率的に伝える必要があります。
繰り返しますが、詳細は実際には特定の状況によって異なります。Googleは、1時間に数百万のWebページにアクセスする数千のWebスパイダーを実行しています。長い間、これは「効率的」でした(「唯一の方法」のように)。少し前に、「サイトマップ」プロトコルが実装されました。これにより、管理者は自分のWebサイトを、Googleのオブザーバーに変更について伝えることができるサブジェクトに変えることができます。
ですから、あなたがしなければならないことのより具体的な例を与えることができない限り、私はあなたにもっと具体的な答えを与えることはできません。デザインパターンでは、座って実際の問題を解決し、脳を活性化する必要があるポイントがあります。
[EDIT3]オブザーバーパターンの使用例をいくつか示します。
多くのUIフレームワークは、このパターンを使用して、イベントを関係者に広めます。Qtには、すべてのサブジェクトが信号(送信する通知)を登録でき、オブザーバーがサブジェクトにアタッチできる中央スポットがあります。これは、すべての接続が管理される単一のスポットがあることを意味します。利点は、このデータ構造をすべてのオブジェクトに追加する必要がないことです。また、外部からのオブジェクト(Qt以外のオブジェクト)はメッセージを送受信できます。すべてが1つの場所にあるため、このデータ構造を簡単に最適化できます。欠点は、この構造が非常に大きくなる可能性があるため、関係するパーティが多い場合(完全に無関係なパーティであっても)、メッセージの送信に時間がかかることです。
Googleはサイトマッププロトコルを使用してウェブサイトをサブジェクトに変換します。これは、URLの最終変更時刻(HTTPGETではなくHTTPHEAD)のみを要求した場合でも、サイト全体を何度もトラバースするよりもはるかに効率的だからです。
WindowsおよびLinuxのファイルシステムは、新しいファイルまたは削除されたファイルについてアプリケーションに通知する通知を提供します。ここでの主な問題は、アプリケーションが実行されていないときにファイルが変更されたときに何が起こるかです。ディレクトリ内のファイルのチェックサムを維持するアプリがあるとします。もちろん、アプリがダウンしたときの変更について知りたいのですが、それは通知サービスが最後に送信した変更を追跡する必要があることを意味します。したがって、ここでは、アプリは起動時にツリー全体を読み取って、見逃した可能性のあるものを確認する必要があり、実行中に発生する変更にはオブザーバーパターンを使用する必要があります。
メールクライアントはオブザーバーです。最後に見た電子メールのIDをメールサーバーに通知し、サーバーは新しい電子メールについて通知します。
複雑なモデルに多くの属性変更がある場合、通常、すべての変更を一元化して(1つの場所で実行する)、そこにオブザーバーをアタッチする(N個のオブザーバーをM個の個別のオブジェクトにアタッチする代わりに)唯一の方法です。この実装では、オブザーバーは「どこでも変更に興味がある」、「任意のサブジェクトのフィールドXの変更」、「サブジェクトYの変更」(通常、最後の変更は「フィールドの変更」を兼ねる)と言うことができます。サブジェクトYのX"-オブザーバーはフィールドへの変更を単に無視します!= X)。