1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【デザインパターン】Observerパターンの学習備忘録

Last updated at Posted at 2024-09-29

概要

Observer パターンは、あるオブジェクト(Subject)の状態が変化した際に、その変化を複数の依存するオブジェクト(Observer)に通知し、オブザーバーがその変化に対応する動作を実行できるようにするデザインパターンである。このパターンは、オブジェクト間の依存を減らし、柔軟な通知システムを実現するのに適している。

利用目的

  • 状態が変わったときに、関連する他のオブジェクトに自動的に通知を行う必要がある場合。
  • 監視対象(Subject)と監視者(Observer)間の結合度を低く保ちながら、柔軟な拡張を可能にする。
  • イベントドリブンなシステムや、リアルタイムで更新が必要な UI コンポーネントなどに使用される。

注意点

  • Observer の数が多い場合、通知処理が重くなる可能性がある。
  • 通知する内容が多岐にわたる場合、通知内容を効率的に設計する必要がある。
  • 循環参照や無限ループを避けるために、適切な管理が必要である。

実装

以下に、Observer パターンを Java で実装した例を示す。この実装では、状態を監視するSubjectと、それに応じて通知を受けるObserverを実装する。

Observer.java
// Observer.java - オブザーバーインターフェース(観察者)

public interface Observer {
    void update(String message);
}
Subject.java
// Subject.java - サブジェクトインターフェース(被観察者、通知者)

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
ConcreteSubject.java
// ConcreteSubject.java - サブジェクトの具体的実装
import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject {
    private List<Observer> observers;
    private String message;

    public ConcreteSubject() {
        this.observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }

}
ConcreteObserver.java
// ConcreteObserver.java - オブザーバーの具体的実装
public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }

}
App.java
// App.java - 実行例
public class App {
    public static void main(String[] args) {
        // サブジェクトを作成
        ConcreteSubject subject = new ConcreteSubject();

        // オブザーバーを作成
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        // オブザーバーをサブジェクトに登録
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        // サブジェクトにメッセージを設定し、オブザーバーに通知
        subject.setMessage("Hello Observers!");

        // Observer 1を削除し、再度通知
        subject.removeObserver(observer1);
        subject.setMessage("Observer 1 has been removed");
    }

}

クラス図

observer_class_diagram.jpg

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?