Observer パターン

 パターン（オブザーバー・パターン）とは、プログラム内のオブジェクトに関するイベント（事象）を他のオブジェクトへ通知する処理で使われるデザインパターンの一種。
通知するオブジェクト側が、通知されるオブジェクト側に観測・観察（）される形になることから、こう呼ばれる。
出版-購読型モデルとも呼ばれる。暗黙的呼び出しの原則と関係が深い。
分散イベント処理システムの実装にも使われる。言語によっては、このパターンで扱われる問題は言語が持つイベント処理構文で処理される。
クラス図.
このパターンの基本は、イベントを通知される側の1つ以上のオブジェクト（オブザーバーまたはリスナーと呼ぶ）を、通知する側のオブジェクト（サブジェクトと呼ぶ）に登録することである。そして通知に使われるメソッドが、抽象メソッドになっていることが重要である。言語によっては、コールバック関数と通知対象コンテキストのペア、あるいはそれらをカプセル化した関数オブジェクト、またはデリゲートが使われる。
以下に、その構造をUMLクラス図で視覚化したものを示す。
各クラスの解説.
このパターンに登場する各インタフェースとインタフェースの実装クラスを、以下で解説する。
Subject.
イベントを通知するオブジェクト側のインタフェース。1つ以上のObserverすなわちイベントを通知されるオブジェクト側のインタフェースの登録・削除・通知のメソッド書式の体裁を提供する。
以下の抽象メソッドを持つ:
上のUMLクラス図では、Subjectがインタフェースと実装クラスに分かれているが、パターン要件ではない。インタフェースを使わずクラスを直接実装することもある。
ConcreteSubject.
Subjectの実装クラス。通知対象であるObserver群を持つ。各Observerが受け取る通知に関する処理を司る。notifyObservers() を呼ぶと、Observer群の1つ以上にイベントを通知する。
Observer.
イベントを通知される側のインタフェース。以下の抽象メソッドを持つ:
ConcreteObserver.
Observerの実装クラス。
典型的用法.
Observer パターンは Model View Controller (MVC) パラダイムの実装に使われることも多い。MVC では、モデルとビューの連携に Observer パターンが使われる。通常、コントローラーがモデルの変化を検出し、ビュー（オブザーバー）に通知する。
コード例.
Python.
以下のコードは Python 3.x で Observer パターンを記述したものである。引数を1つ受け取るcodice_1メソッドを持つオブジェクトであれば、リスナーとして何でも受け付ける（ダック・タイピング）。なお、例ではリスナーの集合を保持するためにリストを使用しているため、同じオブジェクトの多重登録を許可する実装となっている。
class Listener:
 def __init__(self, name):
 self.name = name
 def update(self, event):
 print(self.name, "received event", event)
class Subject:
 def __init__(self):
 self.listeners = []
 def add_listener(self, listener):
 self.listeners.append(listener)
 def remove_listener(self, listener):
 self.listeners.remove(listener)
 def notify_listeners(self, event):
 for listener in self.listeners:
 listener.update(event)
subject = Subject()
listenerA = Listener("<listener A>")
subject.add_listener(listenerA)
listenerB = Listener("<listener B>")
subject.add_listener(listenerB)
subject.notify_listeners("<event 1>")
出力:
<listener A> received event <event 1>
<listener B> received event <event 1>
Java.
ロックを避けるため、を使用する例を示す。スレッドセーフにする必要がない、あるいはcodice_2で同期するのであれば、やを使ってもかまわないが、コンテナの実装によっては順序が保証されず、リスナーを追加したときの順番でcodice_1が呼ばれるとは限らない。
// Listener.java
public interface Listener {
 public void update(String event);
// Subject.java
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.Set;
public class Subject {
 private final Set<Listener> listenerSet = new CopyOnWriteArraySet<Listener>();
 public void addListener(Listener listener) {
 listenerSet.add(listener);
 public void removeListener(Listener listener) {
 listenerSet.remove(listener);
 public void notifyListeners(String event) {
 for (Listener listener : listenerSet) {
 listener.update(event);
// Main.java
class ListenerImpl implements Listener {
 private final String name;
 public ListenerImpl(String name) {
 this.name = name;
 @Override
 public void update(String event) {
 System.out.println(this.name + " received event " + event);
public class Main {
 public static void main(String[] args) throws Exception {
 Subject subject = new Subject();
 Listener listenerA = new ListenerImpl("<listener A>");
 subject.addListener(listenerA);
 Listener listenerB = new ListenerImpl("<listener B>");
 subject.addListener(listenerB);
 subject.notifyListeners("<event 1>");
出力結果はPythonの例と同じである。
実装.
Observer パターンは各種ライブラリやシステムに実装されている。特にGUIツールキットには必ず含まれる。