ギャングが警察とギャングスターの映画でどのように協力したかを今でも覚えていますか?ギャングが強盗になると、1人または2人が常にドアで風を浴びます。動きがある場合、内部の共犯者はすぐに通知され、緊急に後退します。おそらく、ニュースを許可する人は必ずしもその中のすべての共犯者を知っているわけではありません。そして、ニュースをさせてくれる人を知らない新しい弟がいるかもしれません。しかし、これは何もありません。合意されたコードがあるため、コミュニケーションに影響を与えることはできません。
ハハ、エアベンターと上記の泥棒との関係は、現実のオブザーバーパターンの生きた例です。
オブザーバーモードは、パブリッシュ/サブスクライブモードとも呼ばれます。 GOFは、オブジェクト間の1対多くの依存関係を次のように定義します。オブジェクトの状態が変更されると、それに依存するすべてのオブジェクトは通知され、自動的に更新されます。
ここでは、最初にオブジェクト指向のデザインの重要な原則、つまり単一の責任の原則について説明します。したがって、システムの各オブジェクトは、問題ドメインの個別の抽象化に焦点を合わせる必要があります。したがって、理想的には、オブジェクトは1つのことのみを行います。これにより、開発に多くの利点がもたらされます。再利用性とメンテナンスを提供し、リファクタリングの優れた基盤でもあります。
したがって、ほとんどすべての設計パターンは、この基本的な設計原則に基づいています。オブザーバーモデルの起源はGUIとビジネスデータの処理にあるべきだと思います。これは、オブザーバーモデルを説明する例のほとんどがこのトピックであるためです。ただし、オブザーバーモードの適用は、この側面に決して限定されません。
さて、定義の理解には、常に分析するためのインスタンスが必要です。 WeChatサービスアカウントは最近非常に人気があります。 WeChatサービスアカウントの背景を使用して、オブザーバーモデルをお客様に紹介しましょう。
写真を見てください:
各ユーザーには上記の写真に3行があり、写真を明確にするために省略されています。
上の写真に示すように、サービス番号は私たちのテーマであり、ユーザーはオブザーバーです。次に、次の機能を明確にします。
1。サービスアカウントはテーマであり、ビジネスはメッセージをプッシュしています
2.オブザーバーはトピックを購読するだけで、新しいニュースがあるとすぐに送信されます。
3.このトピックメッセージが必要ない場合は、登録解除
4.サービスアカウントがまだそこにある限り、誰かが購読されます。それでは、オブザーバーパターンのクラス図を見てみましょう。
次はコード時間です。WeChat3D宝くじサービスアカウントと一部の加入者をシミュレートします。
まず、トピックインターフェイスとオブザーバーインターフェイスについて書き始めます。
パッケージcom.zhy.pattern.observer; / ** *トピックインターフェイス、すべてのトピックがこのインターフェイスを実装する必要があります * * @author zhy * * */ public interface件名{/ ** *オブザーバーを登録 * * @param observer */ public void registerobserver(オブザーバーオブザーバー); / ** *オブザーバーを削除 * * @paramオブザーバー */ public void removeobserver(オブザーバーオブザーバー); / ***すべてのオブザーバーに通知*/ public void notifyobservers(); }パッケージcom.zhy.pattern.observer; / *** @author zhyすべてのオブザーバーはこのインターフェイスを実装する必要があります*/ public interface observer {public void update(string msg); }次の3Dサービス番号実装クラス:
パッケージcom.zhy.pattern.observer; java.util.arraylistをインポートします。 java.util.listをインポートします。 public class objectfor3dを実装した件名{private list <Observer> observers = new ArrayList <Observer>(); / *** 3D宝くじ番号*/ private string msg; @Override public void RegisterObserver(Observer Observer){Observers.Add(Observer); } @Override public void removeObserver(Observer Observer){int index = observers.indexof(Observer); if(index> = 0){observers.remove(index); }} @Override public void notifyobservers(){for(Observer Observer:Observers){Observer.update(MSG); }} / ** *トピック更新メッセージ * * @param msg * / public void setmsg(string msg){this.msg = msg; notifyobservers(); }}2人のユーザーをシミュレートします。
パッケージcom.zhy.pattern.observer;パブリッククラスObserver1はObserverを実装しています{プライベート主題; public observer1(主題){this.subject = subject; subject.registerobserver(this); } @Override public void update(string msg){system.out.println( "observer1は3D番号 - >" + msg + "を取得します。書き留めたい。"); }}パッケージcom.zhy.pattern.observer; Public Class Observer2はObserverを実装しています{プライベート主題; public observer2(主題){this.subject = subject; subject.registerobserver(this); } @Override public void update(string msg){system.out.println( "observer2は3D番号 - >" + msg + "ルームメイトに伝えたい。"); }}メッセージをサブスクライブするすべてのユーザーがサービスアカウントに維持されていることがわかり、サービスアカウントに新しいメッセージがあるときにすべてのユーザーに通知されます。アーキテクチャ全体はゆるい結合であり、テーマの実装はユーザーに依存しません。新しいユーザーが追加された場合、テーマのコードを変更する必要はありません。ユーザーが取得したデータをどのように処理するかは、テーマとは何の関係もありません。
最後に、テストコードをご覧ください。
パッケージcom.zhy.pattern.observer.test; com.zhy.pattern.observer.objectfor3dをインポートします。 com.zhy.pattern.observer.observerをインポートします。 com.zhy.pattern.observer.observer1をインポートします。 com.zhy.pattern.observer.observer2をインポートします。 com.zhy.pattern.observer.subjectをインポートします。 public class test {public static void main(string [] args){// 3Dサービス番号Objectfor3dをシミュレートするsubjectfor3d = new objectfor3d(); // Customer1 Observer Observer1 = new Observer1(subjectfor3d); Observer Observer2 = new Observer2(subjectfor3d); subjectfor3d.setmsg( "20140420の3D番号IS:127"); subjectfor3d.setmsg( "20140421の3D番号は333"); }}出力結果:
Observer1は3D番号 - > 20140420の3D番号を取得します。127、書き留めたいです。 Observer2は3D番号 - > 20140420の3D番号を取得します。127ルームメイトに伝えたいです。 Observer1は、3D番号 - > 20140421の3D番号を取得します。333、書き留めたいです。 Observer2は3D番号 - > 20140421の3D番号を取得します。333ルームメイトに伝えたいです。
xxxview.addxxxlistenterなど、オブザーバーモードを実装するJDKまたはAndORIDには多くの場所があります。もちろん、xxxview.setonxxxlistenerは必ずしもオブザーバーモードではありません。これは、オブザーバーモードが1対多くの関係であるためです。 setXXXListenerの場合、それは1対1の関係であり、コールバックと呼ばれる必要があります。
オブザーバーモードの学習をおめでとうございます。上記のオブザーバーモードを使用すると、ゼロから書き出すことができます。もちろん、Javaは、java.util.observableとjava.util.observerの助けを借りて、オブザーバーモードの実装を支援してくれました。
以下に、Javaビルトインクラスを使用して、オブザーバーパターンを実装します。
まず第一に、3D宝くじサービス番号のテーマがあります:
パッケージcom.zhy.pattern.observer.java; java.util.observableをインポートします。 Public Class subjectfor3dはObservable {private string msg; public string getMsg(){return msg; } / ** *トピック更新メッセージ * * @param msg * / public void setmsg(string msg){this.msg = msg; setChanged(); notifyobservers(); }}以下は、ダブルカラーボールサービス番号のテーマです。
パッケージcom.zhy.pattern.observer.java; java.util.observableをインポートします。 Public Class subjectforssqは、extends observable {private string msg; public string getMsg(){return msg; } / ** *トピック更新メッセージ * * @param msg * / public void setmsg(string msg){this.msg = msg; setChanged(); notifyobservers(); }}最後に、ユーザー:
パッケージcom.zhy.pattern.observer.java; java.util.observableをインポートします。 java.util.observerをインポートします。 Public Class Observer1はObserverを実装します{public void registersubject(Observable observable){Observable.Addobserver(This); } @Override public void update(Observable o、object arg){if(o instanceof subjectfor3d){subjectfor3d subjectfor3d =(subjectfor3d)o; system.out.println( "subjectfor3dのmsg->" + subjectfor3d.getmsg()); } if(o instanceof subjectforssq){subjectforssq subjectforssq =(subjecforssq)o; system.out.println( "subjectforssqのmsg->" + subjectforssq.getmsg()); }}}テストコードを見てください:
パッケージcom.zhy.pattern.observer.java; public class test {public static void main(string [] args){subjectfor3d subjectfor3d = new subjectfor3d(); subjectforssq subjectforssq = new subjectforssq(); Observer1 Observer1 = new Observer1(); Observer1.registerSubject(subjectfor3d); Observer1.registerSubject(subjectforssq); subjectfor3d.setmsg( "hello 3d'nums:110"); subjectforssq.setmsg( "ssq'nums:12,13,31,5,4,3 15"); }}テスト結果:
subjectfor3dのmsg-> hello 3d'nums:110 subjectforssqのmsg-> ssq'nums:12,13,31,5,4,3 15
Javaビルトインクラスを使用してオブザーバーパターンを実装すると、コードは非常に簡潔であることがわかります。ちなみに、addobserver、removeObserver、NotifyObserversが私たちのために実装されています。観察可能なことは、インターフェイスではなくクラスだけです。基本的に、この本はJavaのデザインに対して否定的な態度を持っています。 Javaの組み込みのオブザーバーパターンは、インターフェイス指向のプログラミングの原則に違反していると感じています。しかし、あなたがそれについて考えるなら、あなたは実際にここでオブザーバーパターンを書いています(私たち自身の実装)。インターフェイスのアイデアは非常に優れていますが、今も多くのトピックを追加し続けると、ddobserver、removeObserver、各トピックのnotifyobserversは基本的に同じです。インターフェイスはコードの再利用を実装できず、結合モードを使用してこれらの3つの方法の再利用を実現する方法はないため、ここでクラスにこれらの3つの方法を実装することは合理的だと思います。