概要
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");
}
}