オブザーバーパターン
オブジェクトの状態変化を複数の依存オブジェクトに自動通知するデザインパターン
設計パターンイベント駆動
オブザーバーパターンとは
オブザーバーパターンは、GoF デザインパターンの 1 つで、Subject (発行者) の状態変化を登録された Observer (購読者) に自動通知する仕組みである。DOM のイベントリスナー、React の再レンダリング、EventBridge がこのパターンの実装。
基本構造
Subject (発行者) がリスナーのリストを保持し、状態変化時に全リスナーに通知する。リスナーは on で登録、off で解除でき、Subject は各リスナーの具体的な処理内容を知らない。この疎結合により、通知先を動的に追加・削除できる。
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 での暗黙のオブザーバー
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 の違いを以下にまとめる。
| 観点 | オブザーバー | Pub/Sub |
|---|---|---|
| 結合度 | Subject が Observer を知っている | ブローカーが仲介 |
| スケール | プロセス内 | プロセス間、サービス間 |
| 例 | EventEmitter | SNS, EventBridge |
オブザーバーパターンの理解を深めるには関連書籍が参考になる。
この記事は役に立ちましたか?
関連用語
デザインパターン
ソフトウェア設計で繰り返し現れる問題に対する再利用可能な解決策のカタログ
EventBridge
AWS のサーバーレスイベントバスで、イベント駆動アーキテクチャの中核を担う
React
コンポーネントベースの UI ライブラリで、宣言的な記法と仮想 DOM で効率的な UI 構築を実現する
オブザーバビリティ
システムの内部状態を外部から観測可能にし、問題の原因を迅速に特定するための仕組み
Flyweight パターン
多数のオブジェクト間で共有可能な状態を分離し、メモリ使用量を削減するデザインパターン
仮想 DOM
実際の DOM の軽量なコピーをメモリ上に保持し、差分だけを効率的に更新する仕組み