プルメカニズムを使用したオブザーバーパターン


10

以下の実装について疑問に思っていました

public void update(Observable obs, Object arg)

私はすべてのオブザーバーに送信し、notifyObserver()Iを使用して更新しthis、オブザーバーに参照を渡すとgetters、サブジェクトのを使用して、必要な情報をプルできます。

argupdateメソッドの引数は何のためのものですか?


@RBT argは、追加オプションとしてのパラメーターまたはパラメーターのグループです
umlcat

回答:


11

Observerパターンを実装する場合、考慮すべき2つの主要なアプローチがあります。「プッシュ」モデルと「プル」モデルです。

「プッシュ」モデルでは、サブジェクト(つまり、Observable)は、必要なすべてのデータを通知時にオブザーバーに送信します。オブザーバーは、サブジェクトに情報を問い合わせる必要はありません。「プル」モデルでは、サブジェクトは何かが起こったことをオブザーバーに通知するだけで、オブザーバーは必要な情報を取得するためにサブジェクトに問い合わせます。

両方のアプローチの長所と短所について説明します。

押す

「プッシュ」モデルの主な利点は、観察者と被験者の間の結合が低いことです。オブザーバーは、対象を照会するために対象について何も知る必要はありません。必要に応じて、次のいずれかを実行する必要があります。A- getサブジェクトでクラス固有のメソッドを呼び出すために、オブザーバー側でダウンキャストを実行します。これは悪いです。B- Observableインターフェイスをよりクラス固有にし、特定のgetメソッドを提供することで、オブザーバーとサブジェクトの間の関係を一般的でなく、物事をより結合します。

「プッシュ」モデルを実装することにより、これをすべて回避します。

ただし、デメリットは柔軟性に欠けます。対象者は、オブザーバーに送信するためにオブザーバーが正確にどのような情報を必要とするかを常に把握しているとは限りません。これはAgeObserver、サブジェクトの「年齢」が変更されたときに通知され、通知時にサブジェクトHeightObserverの最新情報が送信されるような、より具体的なオブザーバーインターフェイスを意味することがよくありますheight

これは1つのオプションです。もう1つは、Info何らかのオブジェクトにカプセル化された大量の情報を送信し、そこからオブザーバーにクエリを送信するサブジェクトです。繰り返しになりますが、正しい情報を送信しているかどうかはわかりません。つまり、これか、またはオブザーバーに特定のオブザーバーインターフェイスを実装するように強制し、オブザーバー側の結合を強化します。

引く

「プル」モデルの欠点についてはすでに触れました。オブザーバーは、適切な情報を照会するために、サブジェクトについての事柄を知る必要があります。これにより、A-ダウンキャスト(醜い)につながるか、B-より具体的なObservableインターフェイスになり、より具体的なアクセサーメソッドが提供されます。たとえばAgeObservablegetAge()メソッドを提供します。

これの利点はより多くの柔軟性です。各オブザーバーは、正しい情報を送信するためにサブジェクトに依存することなく、何を照会するかを自分自身で決定できます。


自分が取り組んでいる特定のプロジェクトにより適した戦略を選択する必要があります。

現実には、あなたは常に、特定の必要があるでしょうObserverし、Observableあなたがとにかく側の間のいくつかのカップリングを持っているので、intefacesを。

だからあなたに一番合ったもので「プル」または「プッシュ」のどちらかを選択してください。

すべてAgeObserverのsは単にage主題の必要がありますか?「プッシュ」モデルを実装します。カップリングが少なく、シンプルです。

すべてHeightObserverのに、対象に関するさまざまな情報が必要ですか?別名、年齢もクエリする必要があり、他のオブジェクトは、身長に加えて体重をクエリする必要がありますか?「プル」モデルを実装します。これにより、Observableインターフェースにアクセサー(ゲッター)を追加する必要があります(これまたは明示的な型のパラメーターとして実際のオブジェクトを渡すかのいずれかですが、インターフェイスを介してこれを行うと、重要ではないものへのオブザーバーのアクセスを拒否できます。それら)。この魂はより高い結合を生み出しますが、より柔軟です。

状況に最も適したものを選択してください。


この説明をありがとうございます。私の質問に戻ると、プルを使用しているときに言ったように、ダウンキャストしてゲッターを使用する必要がありますが、オブザーバーの更新メソッドの引数は何ですか?-public void update(Observable obs、Object arg)?
USer22999299 2014

わかりませんが、これObject argは「プッシュ」モデル用であると思います。ここargで、「情報バンドル」はオブザーバーに送信されます。
Aviv Cohn 2014

ええ、これも私が考えていたものですが、なぜobsを送信するのですか?:)ダウンキャストする場合は、必要な情報だけを取得できます。
USer22999299 2014

1
あなたは「プッシュ」または「プル」について話していますか?「プッシュ」の考え方は、オブザーバー主題のタイプについて知る必要がないということです。したがって、ダウンキャストを避けます。ダウンキャスティングは、2つの側面の間の結合がより緊密になるため、ほとんどの場合悪いことになります。オブザーバーは、目的の正確なタイプを知っており、それが目的全体を打ち破っています。後で新しいクラスがObservableインターフェースを実装するとどうなりますか?サブジェクトの具体的なタイプに依存しない場合(つまり、ダウンキャストを行わない場合)、現在のオブザーバーコードは、新しいサブジェクトで多相的に同様に機能します。
Aviv Cohn 2014

1
オブザーバーコードがダウンキャストに依存している場合、Observableインターフェースを実装するすべての新しいクラスで変更する必要があるため、パターンの目的全体が無効になります。これは、「具体的な実装ではなくインターフェイスへのプログラミング」が優れている理由の例です。インターフェイスに対して機能するコードは、インターフェイスを実装するすべての新しいクラスで変更なしで機能します。たとえばダウンキャストを行うなど、具体的な実装に依存している場合、コードは新しいObservableクラスごとに変更する必要があります。全体の目的を打ち負かした。
Aviv Cohn 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.