オブザーバの設計パターンとパターンコードの構造的特徴-----
Observerパターン(オブザーバーパターン)とは何ですか
オブジェクトの状態が変化するが、それに依存するすべてのオブジェクトが通知され、自動的に更新されたときObserverパターンは、依存会う一対多を説明しました。このモデルの重要な標的である対象(被写体)と観察者(観察者)。ターゲットは、観察者の任意の数はそれに依存することができます。ターゲットの状態が変更されると、すべてのオブザーバに通知されます。この通知に応じて、各オブザーバーミルククエリの目標は、状態同期の対象にします。この相互作用としても知られているサブスクライブ-公開します。目標は、出版社に通知することです。それは、その視聴者を知るために公告を行う必要がない場合。購読と通知を受信する視聴者の任意の数があるかもしれません。
意図:
関連オブジェクト間の整合性を維持する必要性:一般的な副作用を持っているシステムは、コラボレーティブな一連のクラスに分かれています。私たちは、それが彼らの再利用性が低下するため、密結合の様々なタイプの一貫性を維持する必要はありません。したがって、オブジェクトの状態が変化したとき、それに依存するすべてが通知され、自動的に更新されるように、そのような依存関係の多くの関係を定義します。
別名:
リリース依存性(扶養)、---購読(パブリッシュ・サブスクライブ)
参加者:
件名(ターゲット)
- ターゲット視聴者はそれを知っています。同じ目標を観察するためにオブザーバーの任意の数があるかもしれません
- 登録と削除オブザーバオブジェクトのインタフェースを提供
オブザーバー(オブザーバー)
- ターゲット更新の変更が通知されるように定義オブジェクト人のためのインターフェース
ConcreteSubject(ターゲット)
- 様々なオブジェクトに関連した状態ConcreteObserver
- それは、それぞれの視聴者の通知から、状態を変更する場合
ConcreteObserver(特に観察者)
オブジェクト参照へのポインタを維持するConcreteSubject
国家の目的と整合的であるべきである状態に関する店舗情報
自己矛盾の状態の目標を達成するためのオブザーバー・ステータス・アップデート・インターフェース
コラボレーション:
あなたは、独自の変更とのオブザーバーの地位につながったいかなる矛盾のConcreteSubjectイベントをピットインすると、その個々の観察者に通知します
予告変更目標を取得した後、ConcreteObserverオブジェクトは、右の聴衆に情報を照会することができます
適用性:
オブザーバーモードでは、次のいずれかの場合に使用することができます。
抽象モデルは、2つの側面を有する場合の一の態様は、一方に依存しています。これらは、独立して変化させることができるように別のオブジェクト内にカプセル化と再利用の両方
ニーズむ〜、他のオブジェクトを変更しながら変更する必要が正確にどのように多くのオブジェクトを知らなくても、オブジェクトに変更する場合
ときにオブジェクトが他のオブジェクトに通知しなければならないが、それははい、その誰も他のオブジェクトを負いかねます。言い換えれば、あなたは、これらのオブジェクトが緊密に結合されている必要はありません
強みと弱みのObserverパターン
オブザーバーモードでは、あなたがそのオブザーバを多重化することなく、同時に多重観客を分離し、その逆もできる観察者のターゲットと無関係に変更することができます。また、あなたが変更し、観察者の他の目標なしにオブザーバーを増やすことができます。ここでオブザーバーパターンの他のいくつかの長所と短所は以下のとおりです。
対象と観察者との間の抽象的結合
目標は、唯一知っているそれは、オブザーバー抽象クラスインターフェースをシンプルで各行をオブザーバーのシリーズを持っているということです。ターゲットオブジェクトと観察者との間の結合は、抽象的で最小であるように、視聴者のいずれかに属する特定のクラスを知りません
対象と観察者が緊密に結合されていないので、彼らは、システムの抽象化の異なるレベルに属することができます。。下位レベルでターゲット・オブジェクトは、それは、このようにシステム階層の完全性を維持し、より高いレベルの観察者との通信および応答要求であってもよいです
無線通信のサポート
通常の要求通知とは異なり、その対象の受信者を指定せずに送信します。通知は自動的に関連するすべてのオブジェクトにブロードキャストされるには、ターゲットオブジェクトを登録しています。対象読者はどのように多くの関心の対象終わりには気にしません。彼の唯一の責任は、そのオブザーバーのそれぞれに通知することです。これは、あなたの任意の瞬間にオブザーバーを追加したり削除したりする自由を与えます。ハンドルまたは通知は、観測者に依存無視
予期しないアップデート
他のオブザーバーを知らないオブザーバーので、価格を変更するという究極の目標については何も知らないかもしれません。ターゲット上で、一見無害な操作は、オブザーバーのシリーズを引き起こし、これらのオブジェクトは、これらの観測者に依存している更新することがあります。依存しているが、多くの場合、悪いの更新によって引き起こされる、ガイドラインや不適切な保守を定義した場合に加えて、このエラーが頻繁にキャッチすることは困難です
シンプルアップデートプロトコルは、宛先が変更されているものの具体的な詳細を提供していない、これは問題が悪化しています。ヘルプビューアには他の契約が変更されているものを発見しない場合、彼らは変化を少なくしようとするように強制することができます
コード実装手順
テーマやオブザーバーを構築する対象は、インターフェイスであるか、抽象クラスであるObserveable、あります
public interface Subject { //注册观察者 void registerObserver(Observer observe); //解除绑定观察者 void unRegisterObserver(Observer observe); //更新数据 void notifyObservers(); }
インタフェースは、視聴者DevelopmentProgressData.class本実施形態として実装され、進捗情報データがあることトピックの構築
registerObserver(オブザーバー0)メソッドでは、サブスクリプション・リストにオブザーバを追加します
削除オブザーバーunRegisterObserve(オブザーバー0)
public class DevelopmentProgressData implements Subject { private ArrayList arrayObserve; private int completeProgress;//完成进度 private int updateProgress;//更新进度 public DevelopmentProgressData() { arrayObserve = new ArrayList(); } @Override public void registerObserver(Observer observer) { //将观察者添加到列表中 arrayObserve.add(observer); } @Override public void unRegisterObserver(Observer observer) { int i = arrayObserve.indexOf(observer); if (i >= 0) { //将观察者从列表中解除 arrayObserve.remove(i); } } //通知所以观察者数据更新了 @Override public void notifyObservers() { for (int i = 0; i < arrayObserve.size(); i++) { Observer o = (Observer) arrayObserve.get(i); o.update(completeProgress, updateProgress); } } }
オブザーバーオブザーバーインターフェイスの構築
public interface Observer { //更新数据 void update(int completeProgress, int updateProgress); }
インタフェース表示データを構築する(無視できます)
この例を表示するには、このメソッドオブザーバを実装する方法を表示するデータがありますDisplaySchedule
public interface DisplaySchedule { void display(); }
定義されたオブザーバー、インタフェースを実装する必要が、DisplayScheduleを観察(シミュレーションクラスは、視聴者のためのプロダクトマネージャーである)(無視できます)
オブザーバープロパティのテーマに件名、およびProductManagerObserver.class、コールdevelopmentProgressSubject.registerObserver(この)としてコンストラクタオブザーバーとして、リストを見て、視聴者を登録します
public class ProductManagerObserver implements Observer, DisplaySchedule { private int completeProgress;//完成进度 private int updateProgress;//更新进度 //将主题当成观察者的属性 private Subject developmentProgressSubject; public ProductManagerObserver(Subject developmentProgressSubject) { this.developmentProgressSubject = developmentProgressSubject; //注册该观察者 developmentProgressSubject.registerObserver(this); } @Override public void display() { System.out.println("产品经理管理者显示当前数据 完成进度为: " + completeProgress + "更新修改进度为:" + updateProgress); } @Override public void update(int completeProgress, int updateProgress) { this.completeProgress = completeProgress; this.updateProgress = updateProgress; display(); } }
テスト
RunTest.class
public class RunTest { public static void main(String[] args) { DevelopmentProgressData developmentProgressData = new DevelopmentProgressData(); ProductManagerObserver productManagerObserver = new ProductManagerObserver(developmentProgressData); ProjectManagerObserver projectManagerObserver = new ProjectManagerObserver(developmentProgressData); developmentProgressData.setCurrentData(34, 45); //当项目经理出差了,不观察项目进度了就取消订阅了 developmentProgressData.unRegisterObserver(projectManagerObserver); //当前只有产品经理获取到数据 developmentProgressData.setCurrentData(46, 90); } }
出力
C:\Java\jdk1.8.0_161\bin\... 产品经理管理者显示当前数据 完成进度为: 34更新修改进度为:45 项目管理真显示当前数据完成进度为: 34更新修改进度为:45 产品经理管理者显示当前数据 完成进度为: 46更新修改进度为:90 Process finished with exit code 0
参考資料
- 「デザインパターン - 基本的な再利用可能なオブジェクト指向ソフトウェア」
- Observerパターン