序文
新しいことを知っている
最初に、以前に学習した行動パターンを確認します。
- テンプレートメソッドパターン:アルゴリズムのスケルトンを定義し、親クラスで処理します。サブクラスが実装されるまでいくつかの特定のステップが遅延し、ユーザーは親クラステンプレートを再利用できます(ゲストフロー:order- "eat-" pay、特定の食べるものはサブクラス)決定)
- コマンドモード:コマンドをオブジェクトにカプセル化し、コマンドエグゼキューターを集約し、コマンドリクエスターはコマンドオブジェクトを呼び出してコマンド実行を完了するだけでよく、コマンドリクエスターとコマンドエグゼキューターを完全に分離します(リモートコントロールのボタンはコマンドオブジェクトです)。リモコンのボタンを押してライトを切り替えます)
- 訪問者パターン:オブジェクト構造の要素オブジェクトに課せられた操作を分離し、それらを訪問者としてカプセル化します。訪問者が変更してもオブジェクト構造は変更されません(ショッピング、ショッピングカートにさまざまな商品オブジェクトが格納され、顧客はショッピングを表示できます)車内の商品の品質、レジ係はショッピングカート内の商品の価格を確認できます)
- イテレーターモード:集約オブジェクト内の走査オブジェクト関数からストレージオブジェクト関数を分離し、走査オブジェクト関数をイテレーターにカプセル化します。異なる集約オブジェクトに対応するイテレーターを使用するか、異なるイテレーターを置き換えることができます(Linuxカタログからイテレーター)ウェイ記述階層ディレクトリ)
次に、オブザーバーモードの学習を完了します
現実の問題
行動パターンはオブジェクトまたはクラス間の協調行動を表すことを知っています
実生活では、さまざまなオブジェクトが相互に関連付けられています。1つのオブジェクトを変更すると、別のオブジェクトも変更されます。運転中は、信号機、赤信号灯、青信号に遭遇します。気象局の天気予報データが変化します。携帯電話の気象情報は、ブレスビューローの気象データにも対応している必要があります。
気象局の気象データが変化し、APP内のデータも変化しなければならないという観測者モデルの考え方です。
オブザーバーモード
オブザーバーモードとは何ですか?
オブザーバーパターン:オブジェクト間の1対多の依存関係を定義します。これにより、オブジェクトの状態が変化するたびに、関連する依存オブジェクトに通知され、自動的に更新されます。オブザーバーモードは、パブリッシュ/サブスクライブ(パブリッシュ/サブスクライブ)モード、モデルビュー(モデル/ビュー)モード、ソースリスナー(ソース/リスナー)モード、または依存モードとも呼ばれます。オブザーバーパターンはオブジェクトの動作パターンです
なぜオブザーバーモードなのですか?
オブジェクト間の依存関係の存在。観測対象が変更されたかどうかを確認するのではなく、観測対象が変更された場合に自動的に通知したい
例:気象局の気象データが変更された場合、気象局の気象データをチェックするのではなく、気象局が自動的にデータをAPPに送信することを望みます。
変化するオブジェクトを観測対象と呼び、通知されたオブジェクトを観測者と呼びます。観測対象は複数の観測者に対応することができ、これらの観測者間に相互のつながりはありません。必要に応じて観測者を追加、削除してシステムを作ることができます。拡張が容易
オブジェクトとオブジェクト間の依存関係を確立します。オブジェクトが変更されると、他のオブジェクトに自動的に通知され、それに応じて他のオブジェクトが応答します
オブザーバーパターン構造
モードの役割:
-
抽象サブジェクト(Subject)ロール:抽象ターゲットクラスとも呼ばれ、オブザーバーオブジェクトを保存するための集約クラスと、オブザーバーオブジェクトを追加および削除するためのメソッド、およびすべてのオブザーバーに通知するための抽象メソッドを提供します
-
具象サブジェクト(具象サブジェクト)ロール:具象ターゲットクラスとも呼ばれ、抽象ターゲットに通知メソッドを実装し、具象サブジェクトの内部状態が変化したときに、登録されているすべてのオブザーバーオブジェクトに通知します。
-
抽象オブザーバー(オブザーバー)ロール:これは抽象クラスまたはインターフェースであり、それ自体を更新する抽象メソッドを含み、特定のトピックの変更通知を受信したときに呼び出されます
-
具象オブザーバー役割:抽象オブザーバーで定義された抽象メソッドを実装して、ターゲットへの変更が通知されたときにその状態を更新します
パターン実現事例
気象庁の気象情報には、気温、気圧、湿度があります。
気象局に登録されているウェブサイトは2つありますが、気象局は気象情報を更新する度に気象情報を更新しています。
package com.company.Behavioral.observer;
import java.util.ArrayList;
//抽象观察者
interface Observer{
public void update(float temperature,float pressure,float humidity);
}
//具体观察者:QQ
class QQ implements Observer{
private float temperature;
private float pressure;
private float humidity;
//更新信息
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
//展示天气信息
private void display(){
System.out.println("****Today: temperature ="+ temperature + "****");
System.out.println("****Today: pressure ="+ pressure + "****");
System.out.println("****Today: humidity ="+ humidity + "****");
}
}
//具体观察者:baidu
class Baidu implements Observer{
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
private void display(){
System.out.println("****百度网站气温: temperature ="+ temperature + "****");
System.out.println("****百度网站气压: pressure ="+ pressure + "****");
System.out.println("****百度网站湿度: humidity ="+ humidity + "****");
}
}
//接口,由子类实现
interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}
class WeatherData implements Subject{
private float temperature;
private float pressure;
private float humidity;
//观察者集合
private ArrayList<Observer> observers;
public WeatherData() {
this.observers = new ArrayList<Observer>();
}
//注册一个观察者
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
//删除一个观察者
@Override
public void removeObserver(Observer o) {
if (observers.contains(o)) {
observers.remove(o);
}
}
//遍历所有观察者,并通知
@Override
public void notifyObserver() {
for (int i = 0 ; i < observers.size() ; i++){
observers.get(i).update(this.temperature,this.pressure,this.humidity);
}
}
//数据改变时,通知所有观察者
public void dataChange(){
notifyObserver();
}
//数据改变接口
public void setData(float temperature, float pressure, float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
class Client{
public static void main(String[] args) {
//创建一个WeatherData
WeatherData weatherData = new WeatherData();
//创建观察者
QQ qq = new QQ();
Baidu baidu = new Baidu();
//注册
weatherData.registerObserver(qq);
weatherData.registerObserver(baidu);
//数据改变
System.out.println("通知各个观察者");
weatherData.setData(10,100,30);
}
}
気象局のデータ変更がWeatherDataに登録されたオブザーバーを自動的にトラバースするたびに、オブザーバーデータを更新します
モードの利点と欠点
オブザーバーモードが使用されている、使用の過程で、オブザーバーモードの長所と短所を分析して考えることができます。
アドバンテージ
- オブザーバーパターンは、プレゼンテーションレイヤーとデータロジックレイヤーの分離を実現し、安定したメッセージ更新配信メカニズムを定義して更新インターフェースを抽象化するため、さまざまな異なるプレゼンテーションレイヤーを特定のオブザーバーロール(いわゆるMVCパターン)として使用できます。オブザーバーパターンのアイデアに基づいて、データはモデルプレゼンテーションレイヤーを変更し、それに応じて変更されます)
- オブザーバーパターンは、観測対象とオブザーバーの間に抽象的な結合を確立します
- オブザーバーモードはブロードキャスト通信をサポートします
- オブザーバーモードは「開閉原理」の要件を満たしています
短所
- 観測対象に直接および間接の観測者が多い場合、観測者全員に通知するのに時間がかかる
- オブザーバーと観測ターゲットの間に循環依存がある場合、観測ターゲットはそれらの間で循環呼び出しをトリガーし、システムがクラッシュする可能性があります
- オブザーバーモードには、観測されたターゲットオブジェクトがどのように変化したかをオブザーバーに知らせるための対応するメカニズムはありませんが、観測されたターゲットが変化したことを知るだけです。
該当するシーン
- 抽象モデルには2つの側面があり、一方は他方に依存します。これらのアスペクトを個別のオブジェクトにカプセル化して、個別に変更および再利用できるようにする
- 1つのオブジェクトの変更により、変更されるオブジェクトの数が分からないまま、他の1つまたは複数のオブジェクトも変更されます。これにより、オブジェクト間の結合が減少します。
- オブジェクトは、これらのオブジェクトが誰であるかを知らずに他のオブジェクトに通知する必要がある
- システムでトリガーチェーンを作成する必要があります。Aオブジェクトの動作はBオブジェクトに影響し、Bオブジェクトの動作はCオブジェクトに影響します。オブザーバーモードを使用して、チェーントリガーメカニズムを作成できます。
実際の使用
- JavaWebのリスナー
リスナーを本当に理解できますか?-詳細なリスナー
JavaWebのさまざまなリスナーは、オブザーバーモードに基づいており、リスナーモードとも呼ばれます。
例:サーバーでのServletContextドメインオブジェクトの作成と破棄を監視するServletContextListener。ただし、ServletContextのライフサイクルをイベントオブジェクトにカプセル化する点が少し異なります。オブザーバーは、オブザーバーのカスタムをトリガーできるイベントオブジェクトを受け取ります。方法
実際、私たちの前の気象局の場合、気象データをオブジェクトにカプセル化することもできます。オブジェクトの変更はイベントです。
- イベント処理モード
JDK1.1以降のバージョンでは、イベント処理モデルはオブザーバーパターンに基づく委任イベントモデル(DEM)を使用します
イベントのパブリッシャーはイベントソース(イベントソース)と呼ばれ、サブスクライバーはイベントリスナー(イベントリスナー)と呼ばれます。このプロセスでは、イベントオブジェクト(イベントオブジェクト)を使用して、
イベントに関連する情報を転送することもできます。イベントソースオブジェクト、イベントリスニングオブジェクト(イベント処理オブジェクト)とイベントオブジェクトは、Javaイベント処理モデルの3つの要素を構成します
- MVCパターン
SpringMVCのMVCはMVCパターンを指します
MVCパターンは、モデル、ビュー、コントローラーという3つの役割を含むアーキテクチャパターンです。オブザーバーパターンを使用してMVCパターンを実装できます。オブザーバーパターンの観測対象はMVCパターンのモデルであり、オブザーバーはMVCのビューです。コントローラーは2つの間のインターフェースとして機能します。調停者。モデルレイヤーのデータが変更されると、ビューレイヤーはその表示コンテンツを自動的に変更します
SpringMVCは、データ永続化レイヤー、サービスレイヤー、コントロールレイヤー、およびビューレイヤーの分割です。フロントエンドコントローラーDispatcherServlet、処理実行チェーンHandlerExcutionChian、プロセッサマッパーHandlerMapping、プロセッサアダプターHandlerAdapter、ビューリゾルバーViewResolverおよびその他のコンポーネントを使用して、レベル間を実現しますデータ送信、完全な分離
一般的に、オブザーバーモードは非常に便利なモードであり、よく使用されます。
まとめ
- オブザーバーモード:オブジェクト間の依存関係を定義し、ターゲットオブジェクトの状態が変化したときに、関連する依存オブジェクトに自動的に通知し、自動的に更新します
- オブザーバーパターンには4つの役割があります。抽象ターゲットクラス、具象ターゲットクラス、抽象オブザーバー、具象オブザーバーです。
- 特定のターゲットクラスは、抽象ターゲットクラスの抽象メソッドを実装し、その状態が変化すると、登録されているオブザーバーに自動的に通知します;特定のオブザーバーは、抽象オブザーバーのメソッドを実装し、特定のターゲットクラスが通知すると、その状態を自動的に更新します
- オブザーバーモードの利点:プレゼンテーションレイヤーとデータロジックレイヤーの分離の実現、ブロードキャスト通信のサポート、観測ターゲットとオブザーバー間の抽象的な結合の確立
- オブザーバーモードの欠点:オブザーバーが多すぎる場合、通知に時間がかかります。オブザーバーとターゲットクラスに循環依存がある場合、システムがクラッシュします。
- オブザーバーパターンが適用可能:抽象モデルには依存関係があり、1つのオブジェクトを変更すると、変更されたオブジェクトの数を知らなくても他のオブジェクトが変更されます。システムにはトリガーチェーンが必要です
- オブザーバーパターンには、JavaWebのコンポーネントリスナー、Javaのイベント処理パターン、Spring MVCのMVCパターンなどの多くの実用的な用途があり、オブザーバーパターンのアイデアを使用しています。