オブザーバーパターン

オブジェクトの状態変化を複数の依存オブジェクトに自動通知するデザインパターン

設計パターンイベント駆動

オブザーバーパターンとは

オブザーバーパターンは、GoF デザインパターンの 1 つで、Subject (発行者) の状態変化を登録された Observer (購読者) に自動通知する仕組みである。DOM のイベントリスナー、React の再レンダリング、EventBridge がこのパターンの実装。

基本構造

type Listener<T> = (data: T) => void;

class EventEmitter<T> {
  private listeners: Listener<T>[] = [];
  on(listener: Listener<T>) { this.listeners.push(listener); }
  off(listener: Listener<T>) { this.listeners = this.listeners.filter(l => l !== listener); }
  emit(data: T) { this.listeners.forEach(l => l(data)); }
}

const emitter = new EventEmitter<string>();
emitter.on((msg) => console.log(`A: ${msg}`));
emitter.on((msg) => console.log(`B: ${msg}`));
emitter.emit('hello'); // A: hello, B: hello

実装例

実装 説明
DOM EventListener element.addEventListener('click', handler)
Node.js EventEmitter emitter.on('data', handler)
React useState 状態変更 → 再レンダリング (暗黙のオブザーバー)
EventBridge イベント → ルール → ターゲット

React での暗黙のオブザーバー

function Counter() {
  const [count, setCount] = useState(0);
  // setCount が呼ばれると、React が自動的に再レンダリング
  // → useState は暗黙のオブザーバーパターン
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

メモリリークの防止

// ❌ リスナーの解除を忘れる → メモリリーク
useEffect(() => {
  window.addEventListener('resize', handleResize);
}, []);

// ✅ クリーンアップで解除
useEffect(() => {
  window.addEventListener('resize', handleResize);
  return () => window.removeEventListener('resize', handleResize);
}, []);

オブザーバー vs Pub/Sub

観点 オブザーバー Pub/Sub
結合度 Subject が Observer を知っている ブローカーが仲介
スケール プロセス内 プロセス間、サービス間
EventEmitter SNS, EventBridge

オブザーバーパターンの理解を深めるには関連書籍が参考になる。

関連用語