0Pricing
Java Academy · レッスン

Observer パターン:イベント通知

株価システムで Observer を実装し、イベントの生成側と利用側を分離します。

「Observer パターン:イベント通知」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

Observer の目的

Observer(Publish-Subscribe とも呼ばれます)は、1対多の依存関係を定義します。サブジェクトの状態が変化すると、登録されているすべてのオブザーバーに自動的に通知されます。

サブジェクトとオブザーバーのインターフェース

サブジェクトはオブザーバーのリストを管理し、通知を送ります。オブザーバーは update メソッドを実装してイベントに反応します。

public interface Observer {
    void update(String event, Object data);
}
public interface Subject {
    void addObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers(String event, Object data);
}

具象サブジェクト: 株価ティッカー

サブジェクトは状態を保持し、状態が変化するたびに notifyObservers を呼び出します。また、オブザーバーのリストを管理します。

public class StockTicker implements Subject {
    private final List<Observer> observers = new ArrayList<>();
    private double price;
    public void addObserver(Observer o)    { observers.add(o); }
    public void removeObserver(Observer o) { observers.remove(o); }
    public void setPrice(double p) {
        this.price = p;
        notifyObservers("PRICE_CHANGED", p);
    }
    public void notifyObservers(String ev, Object data) {
        for (Observer o : observers) o.update(ev, data);
    }
}

具象オブザーバー

各オブザーバーは、同じ通知に対してそれぞれ異なる反応をします。サブジェクトを変更せずに、実行時にオブザーバーを追加できます。

public class AlertSystem implements Observer {
    public void update(String ev, Object data) {
        if ((double) data < 100) System.out.println("ALERT: Low price!");
    }
}
public class Logger implements Observer {
    public void update(String ev, Object data) {
        System.out.println("LOG: " + ev + " = " + data);
    }
}

オブザーバーの接続

サブジェクトにオブザーバーを登録します。サブジェクトが変化すると、登録されたすべてのオブザーバーが反応します。更新の受信を停止するには登録を解除します。

StockTicker ticker = new StockTicker();
ticker.addObserver(new AlertSystem());
ticker.addObserver(new Logger());
ticker.setPrice(95.5); // both observers notified

java.util.Observable — 非推奨

JDK には java.util.Observable と java.util.Observer がありましたが、Java 9 以降では非推奨です。独自に実装するか、RxJava や Project Reactor などのリアクティブライブラリを使用してください。

PropertyChangeListener

JavaBeans には PropertyChangeSupport が用意されています。これは Bean のプロパティ変更に対応する組み込みのオブザーバー機構で、Swing や JavaFX で広く使われています。

public class Model {
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private int value;
    public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); }
    public void setValue(int v) {
        int old = this.value; this.value = v;
        pcs.firePropertyChange("value", old, v);
    }
}

Consumer を使った関数型オブザーバー

専用のインターフェースを定義する代わりに、軽量なオブザーバーとして Consumer<T> を使えます。単純なイベントコールバックに最適です。

List<Consumer<Double>> listeners = new ArrayList<>();
listeners.add(p -> { if (p < 100) System.out.println("Low price"); });
listeners.add(p -> System.out.println("Price: " + p));
double newPrice = 95.5;
listeners.forEach(l -> l.accept(newPrice));

Observer と Event Bus の比較

Event Bus(Guava EventBus など)は、サブジェクトとオブザーバーをさらに疎結合にします。サブジェクトは誰がリッスンしているかを知らずに、Event Bus にイベントをポストできます。オブザーバーはメソッドのアノテーションによって購読します。

// Guava EventBus example
EventBus bus = new EventBus();
bus.register(new Logger());       // subscribe
bus.post(new PriceEvent(95.5));   // publish

Observer におけるスレッドセーフティ

複数のスレッドからオブザーバーを追加・削除できる場合は、synchronized でリストを保護するか、通知が多い処理では CopyOnWriteArrayList を使用してください。

private final List<Observer> observers = new CopyOnWriteArrayList<>();

メモリリークの回避

オブザーバーのリストに強い参照を保持すると、GC がオブザーバーを回収できなくなります。WeakReference<Observer> を使うか、不要になったオブザーバーの登録を必ず解除してください。

実際のフレームワークにおける Observer

Spring の ApplicationEventPublisher、Android LiveData、JavaFX のプロパティは、いずれも異なる抽象度で実装された Observer パターンです。

確認問題

Observer パターンの主な利点は何ですか。

まとめ

Observer は、1対多の通知チェーンを定義します。インターフェースまたは関数型の Consumer を使って実装できます。スレッドセーフティには CopyOnWriteArrayList を使用し、メモリリークを防ぐためにオブザーバーの登録を必ず解除してください。

よくある質問

「Observer パターン:イベント通知」レッスンは無料ですか?

はい。「Observer パターン:イベント通知」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「Observer パターン:イベント通知」で何を学びますか?

株価システムで Observer を実装し、イベントの生成側と利用側を分離します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「Observer パターン:イベント通知」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Observer パターン:イベント通知
  2. Strategy パターン:交換可能なアルゴリズム
  3. Command パターン:操作のカプセル化
  4. Template Method:アルゴリズムの骨格定義
← Java Academyに戻る