mcpField
G
gof-observer

gof-observer

github.com/yonatankarp開発143 回インストール23 週間前に更新
リポジトリ

gof-observer について

Subject の状態変化を複数の依存先へ通知する Observer パターンを解説するスキルです。プロセス内の更新設計に役立ち、プッシュとプルの使い分けや実装上の注意点も扱います。

主な機能

  1. 01Subject と Observer の役割
  2. 02登録と解除のライフサイクル
  3. 03プッシュ型とプル型の通知
  4. 04別の方式を選ぶ判断指針
  5. 05Observer のよくある落とし穴

活用シーン

  1. 01複数のビューと状態の同期
  2. 02イベント発生時の購読者への通知
  3. 03発行元と依存先の疎結合化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yonatankarp/software-design-skills --skill gof-observer

インストール後、Claude Code で/gof-observerを入力して読み込まれたか確認します。

詳細

1行でまとめると

1つのオブジェクト(サブジェクト)の状態が変化したとき、その依存先(オブザーバー)すべてに自動で通知する一対多の依存関係を定義します。サブジェクトは、依存先の具体的な型を知る必要がありません。

このスキルを使う場面

  • 1つのオブジェクトが正規の状態を保持し、複数のオブジェクトがその状態に同期する必要がある場合(データ → 複数のビュー、モデル → 複数のリスナー)。
  • イベント形式の結合:「X が起きたら、これら N 個の処理を実行する」という要件があり、対象となる処理が増えていく場合。
  • パブリッシャーが知るべきではない複数のサブスクライバーから、パブリッシャーを分離する場合。

このスキルを使わない場面

  • 下流のコンシューマーが1つだけの場合 — 直接呼び出すほうが簡単です。
  • 通知を同期的に行い、サブスクライバーの処理が完了するまでサブジェクトの進行を止める必要がある場合 — 一般的な Observer の実装はプッシュ形式で、サブスクライバーが独立していることを前提とします。
  • イベントソーシング、リプレイ、永続化が必要な場合 — それにはプロセス内の Observer パターンではなく、本格的なイベントバス/メッセージブローカーが必要です。

主な内容

サブジェクトが認識するのは、Observer インターフェース上の notify() メソッドだけです。具象オブザーバーは attach() / detach() で登録・解除します。サブジェクトの状態が変化すると、オブザーバーのリストを順に処理し、それぞれに notify() を呼び出します。

プッシュとプル:

  • プッシュ — サブジェクトが変更されたデータを notify(data) に渡します。シンプルですが、サブジェクトはオブザーバーが何を必要としているかを把握します。
  • プル — サブジェクト自身を渡し、オブザーバーが必要なデータを問い合わせます。結合がより緩やかになり、オブザーバーは必要なデータだけを取得します。

多くの最新フレームワーク(RxJava、Kotlin Flow、EventBus ライブラリ、JavaFX のバインディング、さらには DOM のイベントリスナー)では、Observer の派生パターンが実装されています。

判断の目安

  • オブザーバーが同じデータを必要とするならプッシュで問題ありません。サブジェクトの状態の異なる一部だけを必要とするなら、プルが適しています。
  • オブザーバーインターフェースは(1つのメソッドに)絞りましょう。肥大化したオブザーバーインターフェースは、保守の負担になります。
  • サブスクライバーが数人を超える場合や、プロセスをまたいだ結合がある場合は、Observer を独自に実装するのではなく、本格的なイベントバス(Kafka、RabbitMQ、Spring の ApplicationEventPublisher)を使いましょう。

アンチパターン

  • オブザーバーの登録解除を忘れることによるメモリリーク(サブジェクトがオブザーバーを保持し続けます) — 登録解除を明示し、テストしましょう。
  • notify() 中にサブジェクトを変更するオブザーバー — 再入可能性に関する不具合や、オブザーバーリストの無効化を引き起こします。
  • 通知の順序に依存するオブザーバー — Observer が保証するのは通知であり、順序ではありません。順序が重要なら、別のパターンが必要です。

関連項目

  • gof-command — 「通知」をキューに入れたり、取り消し可能にしたり、パラメーター化したりする必要がある場合に使います。
  • gof-kotlin-idioms — Kotlin では、Flow、SharedFlow、StateFlow が Observer 型のプリミティブとして標準で用意されています。独自の Observer を実装する必要はほとんどありません。

参考資料

  • Head First Design Patterns 第2版、第2章(「オブジェクトに情報を伝える:Observer パターン」) — 天気観測所を題材にした、定番の解説です。

コメント