forループのプログラミングを停止します。JDKに付属するオブザーバーモードは非常に香りがよいです。

みなさん、こんにちは。まだforループのプログラミングをしていますか?

 

他に誰がオブザーバーパターンを使用できないのですか?

この記事は「オブザーバーモード」の理論と実際の戦闘をもたらします

オブザーバーパターンとは何ですか?

Observer Patternは、オブジェクト間の1対多の依存関係を定義します。これにより、オブジェクトの状態が変化する限り、依存するすべての関連オブジェクトが通知され、自動的に更新されます。

オブザーバーモードでは、変更されるオブジェクトをオブザーバーと呼び、更新を通知されるオブジェクトをオブザーバーと呼びます。1つのオブザーバーターゲットは複数のオブザーバーに対応します。オブザーバーは通常、動的に追加できるリストコレクションです。必要に応じて削除します。簡単に拡張できます。

オブザーバーパターンを使用する利点は、観測ターゲットとオブザーバーの間に抽象的な緩い結合関係があり、2つの間の結合関係が減少することです。

パブリッシュ/サブスクライブモデル

オブザーバーモードは、多くの場所でパブリッシュ/サブスクライブモード(パブリッシュ/サブスクライブ)とも呼ばれます。実際、このように理解できますが、両者の間にはまだわずかな違いがあります。

オブザーバーモードのオブザーバーは、オブザーバーモードに直接バインドされており、オブザーバーターゲットはオブザーバーリストのセットを維持する必要があります。この2つは、インターフェイスに基づいて依存関係が組み合わされているため、オブザーバーモードは緩く結合されていますが、完全に分離されていません。

パブリッシュ/サブスクライブモデルでは、パブリッシャーとサブスクライバーの間に接続はありません。パブリッシャーはミドルパーティを介してトピック(トピック)をパブリッシュし、サブスクライバーはミドルパーティ(スケジューリングセンター)を介してトピック(トピック)をサブスクライブします。サブスクライブの変更はサブスクライバーに直接通知されませんが、仲介者を介して通知されるか、サブスクライバーが自分で仲介者からプルするため、パブリッシュ/サブスクライブモデルは完全に分離されます。

彼らの関係を理解するための写真:

オブザーバーパターンとサブスクリプション発行パターンの違い

写真からは違いがあり、どちらもオブザーバーモードと呼ばれ、問題はありません。

オブザーバーモードホイール

オブザーバーモードが広く使用されているため、JDKツールキットにはバージョン1.0からのオブザーバーモードテンプレートセットが付属しています。そのテンプレートに従ってオブザーバーモードを簡単に実装でき、ホイールを繰り返す必要はありません。

オブザーバーターゲットクラス:

java.util.Observable

最も重要な2つの変数は次のとおりです。

  • 変更:ターゲットの状態が変更されたかどうかを確認します。デフォルトは次のとおりです。false;
  • obs:オブザーバーリスト(オブザーバー)、スレッドセーフリストコレクション:Vector、デフォルトは空のコレクションです。

その中の重要な方法は、すべて観測対象と観測者の状態に関係しているので、一目でわかるのでここでは紹介しません。

オブザーバーインターフェース:

java.util.Observable

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}

オブザーバーインターフェイスには更新メソッドが1つだけあります。これは、オブザーバーに自分自身を更新するように通知するために使用されます。

動作中のオブザーバーモード

OK、JDKにはこれら2つの機能が付属していることを知っているので、簡単なオブザーバーモードのアプリケーションシナリオを実装して、パブリックアカウントでの記事のプッシュをシミュレートしましょう。監視対象は私、ウェブマスター、オブザーバーはすべてです。パブリックではありません。Javaテクノロジースタックが記事をプッシュすると、すべてのユーザーが更新通知を受信して​​読むことができます。

新しい観測対象クラス:

import lombok.Getter;

import java.util.Observable;

/**
 * 观察目标:栈长
 * 来源微信公众号:Java技术栈
 */
@Getter
public class JavaStackObservable extends Observable {

    private String article;

    /**
     * 发表文章
     * @param article
     */
    public void publish(String article){
        // 发表文章
        this.article = article;

        // 改变状态
        this.setChanged();

        // 通知所有观察者
        this.notifyObservers();
    }

}

オブザベーションターゲットのロジックは、最初に記事を公開し、次にオブザベーションターゲットの状態を変更してから、すべてのオブザーバーに通知することです。

notifyObserversメソッドのソースコードに焦点を当てましょう。

最初に同期ロックを取得し、状態が更新されているかどうかを判断し、更新されている場合は、監視ターゲットの状態をクリアしてから、forループを使用してすべてのオブザーバーをトラバースし、オブザーバーのupdateメソッドを呼び出してオブザーバーに更新を通知します。

オブザーバークラスを追加します。

import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import java.util.Observable;
import java.util.Observer;

/**
 * 观察者:读者粉丝
 * 来源微信公众号:Java技术栈
 */
@RequiredArgsConstructor
public class ReaderObserver implements Observer {

    @NonNull
    private String name;

    private String article;

    @Override
    public void update(Observable o, Object arg) {
        // 更新文章
        updateArticle(o);
    }

    private void updateArticle(Observable o) {
        JavaStackObservable javaStackObservable = (JavaStackObservable) o;
        this.article = javaStackObservable.getArticle();
        System.out.printf("我是读者:%s,文章已更新为:%s\n", this.name, this.article);
    }

}

オブザーバーのロジックは、オブザーバーターゲットインスタンスオブジェクトを取得し、オブザーバーターゲットオブジェクトの記事情報を独自の記事情報に更新し、最後にその記事が更新されたことを出力することです。

オブザーバーは、呼び出し通知のターゲットを監視するために使用されるオブザーバーインターフェイスの更新メソッドを実装するだけで済みます。

このチュートリアルの実際のソースコードはすべて、次のリポジトリにアップロードされています:https://github.com/javastacks/javastack

観測対象と観測者クラスの構造図は次のとおりです。

新しい試験クラス:

/**
 * 观察者:读者粉丝
 * 来源微信公众号:Java技术栈
 */
public class ObserverTest {

    public static void main(String[] args) {
        // 创建一个观察目标
        JavaStackObservable javaStackObservable = new JavaStackObservable();

        // 添加观察者
        javaStackObservable.addObserver(new ReaderObserver("小明"));
        javaStackObservable.addObserver(new ReaderObserver("小张"));
        javaStackObservable.addObserver(new ReaderObserver("小爱"));

        // 发表文章
        javaStackObservable.publish("什么是观察者模式?");
    }

}

オブザーバーとオブザーバーを作成するためのシーケンス要件はありません。重要な点は、オブザーバーに通知する記事を公開する前に、オブザーバーリストにオブザーバーターゲットを追加する必要があるということです。

出力結果:

この簡単な記事のプッシュ練習を通じて、誰もがオブザーバーパターンの基本を理解している必要があります。実際の作業では、使用できるシナリオが多数あり、オブザーバーパターンは1対多の依存関係について考慮することができます。

要約する

簡単ではありませんが、次々と長時間働いた後、オブザーバーモードを習得しましたか?

オブザーバーパターンのメリットは、オブザーバーターゲットとオブザーバーを分離することであり、デメリットも明らかです。上記の例から、オブザーバーオブジェクトが多すぎると、メモリリークが発生する可能性があることがわかります。

さらに、パフォーマンスの観点から、すべてのオブザーバーの更新はループでキューに入れられるため、オブザーバーの更新操作は非同期スレッドと見なすことができ(またはスレッドプールを使用できます)、全体的な効率が向上します。

このチュートリアルの実際のソースコードはすべて、このリポジトリにアップロードされています。

https://github.com/javastacks/javastack

おすすめ

転載: blog.csdn.net/m0_63437643/article/details/123774254