オブザーバー パターンは動作設計パターンです。 Observer パターンは、オブジェクトの状態に興味があり、変更されるたびに通知を受け取りたい場合に使用します。オブザーバーパターンでは、他のオブジェクトの状態を観測するオブジェクトをオブザーバーと呼び、観測されるオブジェクトをサブジェクトと呼びます。 GoF ルールによれば、Observer パターンの目的は次のとおりです。
次のようにコードをコピーします。
オブジェクト間の 1 対多の依存関係を定義します。オブジェクトの状態が変化すると、他の関連オブジェクトが通知され、自動的に更新されます。
サブジェクトには、状態が変化したときに通知を受ける必要があるオブザーバーが含まれています。したがって、オブザーバーに自分自身を登録および登録解除する方法を提供する必要があります。サブジェクト (監視対象) が変更された場合、すべてのオブザーバーに通知するメソッドも含める必要があります。オブザーバーに通知するときは、更新をプッシュするか、更新を取得するための別の方法を提供できます。
オブザーバーには、オブザーバー オブジェクトを設定し、オブザーバーが更新を通知するために使用できるメソッドが必要です。
JAVA には、オブザーバー パターン、java.util.Observable および java.util.Observer インターフェイスを実装するための組み込みの方法が用意されています。ただし、あまり広く使用されていません。この実装は単純すぎるため、JAVA クラスは複数回継承できないため、ほとんどの場合、最後の拡張クラスにオブザーバー パターンだけを実装させることは望ましくありません。
Java Messages Service (JMS) メッセージ サービスは、オブザーバー モードとコマンド モードを使用して、異なるプログラム間でのデータのパブリケーションとサブスクリプションを実現します。
MVC モデル ビュー コントロール フレームワークもオブザーバー パターンを使用し、モデルを観察対象として扱い、ビューをオブザーバーとして扱います。ビューは自身をモデルに登録して、モデルへの変更を受け取ることができます。
オブザーバーパターンの例
この例では、簡単なトピックのディスカッションを完了し、オブザーバーはこのトピックに登録できます。このトピックに関するコンテンツの送信に起因する変更は、登録されているすべてのオブザーバーに通知されます。
サブジェクトのオブザーバーのニーズに基づいて、基本的なサブジェクト インターフェイスを実装します。このインターフェイスは、その後インターフェイスを実装する特定のクラスに実装する必要がある一連の特定のメソッドを指定します。
次のようにコードをコピーします。
パッケージ com.journaldev.design.observer;
パブリックインターフェイスの件名 {
//オブザーバーを登録および登録解除するメソッド
public void register(オブザーバー obj);
public void unregister(Observer obj);
//オブザーバーに変更を通知するメソッド
public void NoticeObservers();
// 件名から更新情報を取得するメソッド
public Object getUpdate(Observer obj);
}
次に、関連付けられたオブザーバーを作成します。サブジェクトをオブザーバーにアタッチするメソッドが必要です。追加のメソッドは件名変更通知を受け入れることができます。
次のようにコードをコピーします。
パッケージ com.journaldev.design.observer;
パブリック インターフェイス オブザーバー {
//サブジェクトが使用するオブザーバーを更新するメソッド
public void update();
// 観察対象を添付します
public void setSubject(Subject sub);
}
この接続は確立されました。次に、具体的なテーマを実行します。
次のようにコードをコピーします。
パッケージ com.journaldev.design.observer;
java.util.ArrayListをインポートします。
java.util.Listをインポートします。
public class MyTopic は Subject { を実装します。
private List<Observer> オブザーバー。
プライベート文字列メッセージ。
プライベートブール値が変更されました。
プライベート最終オブジェクト MUTEX= new Object();
public MyTopic(){
this.observers=new ArrayList<>();
}
@オーバーライド
public void register(オブザーバー obj) {
if(obj == null) throw new NullPointerException("Null Observer");
if(!observers.contains(obj)) observers.add(obj);
}
@オーバーライド
public void unregister(Observer obj) {
オブザーバー.remove(obj);
}
@オーバーライド
public void NoticeObservers() {
List<Observer> オブザーバーローカル = null;
//同期は、メッセージの受信後に登録されたオブザーバーに通知されないようにするために使用されます。
同期 (MUTEX) {
もし(!変わった)
戻る;
observersLocal = new ArrayList<>(this.observers);
this.changed=false;
}
for (オブザーバー obj :observersLocal) {
obj.update();
}
}
@オーバーライド
public Object getUpdate(Observer obj) {
このメッセージを返します;
}
//トピックにメッセージを投稿するメソッド
public void postMessage(String msg){
System.out.println("トピックに投稿されたメッセージ:"+msg);
this.message=msg;
this.changed=true;
通知オブザーバー();
}
}
オブザーバー メソッドの登録と登録解除の実装は非常に簡単です。追加のメソッド postMessage() は、このトピックに文字列メッセージを送信するためにクライアントによって使用されます。ブール変数は、トピックの状態の変化を追跡し、そのような変化をオブザーバーに通知するために使用されることに注意してください。この変数が必要なのは、更新がないにもかかわらず、誰かが NoticeObservers() メソッドを呼び出した場合、オブザーバーにエラー通知情報を送信できないためです。
さらに、メッセージがトピックにパブリッシュされる前に、登録されたオブザーバーにのみ通知が送信されるようにするために、notifyObservers() で同期が使用されることに注意してください。
以下はオブザーバーの実装です。彼らは常に被写体オブジェクトに焦点を合わせます。
次のようにコードをコピーします。
パッケージ com.journaldev.design.observer;
public class MyTopicSubscriber は Observer {を実装します。
プライベート文字列名。
プライベートサブジェクトトピック。
public MyTopicSubscriber(String nm){
this.name=nm;
}
@オーバーライド
public void update() {
String msg = (String) topic.getUpdate(this);
if(msg==null){
System.out.println(name+":: 新しいメッセージはありません");
}それ以外
System.out.println(name+":: メッセージを消費しています::"+msg);
}
@オーバーライド
public void setSubject(Subject sub) {
this.topic=サブ;
}
}
update() メソッドの実装では、オブザーバーの getUpdate() を使用して更新されたメッセージを処理することに注意してください。ここでは、メッセージをパラメータとして update() メソッドに渡すことは避けてください。
以下は、トピック クラスの実装を検証するための簡単なテスト プログラムです。
次のようにコードをコピーします。
パッケージ com.journaldev.design.observer;
パブリック クラス ObserverPatternTest {
public static void main(String[] args) {
//件名を作成
MyTopic トピック = new MyTopic();
//オブザーバーを作成する
オブザーバー obj1 = new MyTopicSubscriber("Obj1");
オブザーバー obj2 = new MyTopicSubscriber("Obj2");
オブザーバー obj3 = new MyTopicSubscriber("Obj3");
// オブザーバーをサブジェクトに登録します
トピック.レジスタ(obj1);
トピック.レジスタ(obj2);
トピック.レジスタ(obj3);
// オブザーバーをサブジェクトにアタッチします
obj1.setSubject(トピック);
obj2.setSubject(トピック);
obj3.setSubject(トピック);
// 利用可能なアップデートがあるかどうかを確認する
obj1.update();
//件名にメッセージを送信します
topic.postMessage("新しいメッセージ");
}
}
上記の出力は次のとおりです。
次のようにコードをコピーします。
Obj1:: 新しいメッセージはありません
トピックに投稿されたメッセージ: 新しいメッセージ
Obj1::消費メッセージ::新しいメッセージ
Obj2::メッセージを消費しています::新しいメッセージ
Obj3::メッセージを消費中::新しいメッセージ</pre>
Observer パターンの UML 図
オブザーバー パターンは、パブリッシュ/サブスクライブ パターンとも呼ばれます。 JAVA の具体的なアプリケーションのいくつかは次のとおりです。
1.Swing の java.util.EventListener
2.javax.servlet.http.HttpSessionBindingListener
3.javax.servlet.http.HttpSessionAttributeListener
上記はすべてオブザーバー モードです。すでに気に入っていただければ幸いです。コメントであなたの気持ちを共有したり、他の人と共有してください。