0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するObserverパターン:通知と依存の明示化による反応的設計

Posted at

概要

Observer(オブザーバー)パターンは、
あるオブジェクトの状態変化を監視し、変化に応じて他のオブジェクトが自動的に通知を受け取るようにする設計パターンである。

Pub/Subモデルやイベントリスナ、リアクティブプログラミングの基礎概念として広く活用される。


1. なぜObserverが必要か?

❌ 状態変更を受け取るオブジェクトを明示的に呼び出す必要がある

def update():
    label.text = model.value
    logger.log("updated")

変更対象が増えると呼び出し側の責任が肥大化


✅ 依存オブジェクトが自動的に通知を受ける構造に変更

model.subscribe(label.update)
model.subscribe(logger.log)

通知と依存の分離が実現し、保守性が向上


2. 基本構造

✅ Subject(観察対象)

class Subject:
    def __init__(self):
        self._observers = []

    def subscribe(self, observer):
        self._observers.append(observer)

    def unsubscribe(self, observer):
        self._observers.remove(observer)

    def notify(self, value):
        for observer in self._observers:
            observer(value)

✅ 使用する側のロジック

class Logger:
    def log(self, value):
        print(f"[Logger] value changed to: {value}")

class Label:
    def update(self, value):
        print(f"[Label] displaying: {value}")

✅ 使用例

subject = Subject()
logger = Logger()
label = Label()

subject.subscribe(logger.log)
subject.subscribe(label.update)

subject.notify("Hello World")

出力:

[Logger] value changed to: Hello World  
[Label] displaying: Hello World

3. Python的応用:@property に組み込むリアクティブ風モデル

class ReactiveValue:
    def __init__(self, initial=None):
        self._value = initial
        self._observers = []

    def subscribe(self, fn):
        self._observers.append(fn)

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new):
        self._value = new
        for fn in self._observers:
            fn(new)
rv = ReactiveValue()
rv.subscribe(lambda v: print(f"Reactive update: {v}"))
rv.value = 42

最小構成のリアクティブシステムとして活用可能


4. 実務ユースケース

✅ GUIコンポーネントとモデルのバインディング

モデル更新に応じて自動でUIを更新


✅ イベント駆動アーキテクチャ

→ モジュール間の依存を明示せず、非同期かつ柔軟な通信を実現


✅ 状態管理ライブラリ(ReduxやMobXなど)での反応設計

→ 状態変化に応じてサブスクライバが反応的に振る舞う


✅ 通知システム(Slack通知、Webhook、メール送信など)

システムイベントを検知し、対応処理を動的に定義


5. よくある誤用と対策

❌ 監視対象と通知先の結合が強い

→ ✅ 関数/コールバック/イベント名などで疎結合を保つ


❌ 無限ループになる(相互通知)

→ ✅ 通知元と通知先の依存関係を明示管理し、ループ対策を入れる


❌ オブザーバが大量に増え、パフォーマンス劣化

→ ✅ 一度だけ通知されるonce、条件付き通知filterなどの設計を導入


結語

Observerパターンとは、“変化に応じた反応を、構造として設計する技法”である。

  • 状態変化に応じた処理を自動通知することで、直感的かつ柔軟な構造が可能に
  • モデルと表示、データと処理の依存関係を明示的に切り離し、保守性・再利用性を向上
  • Pythonでは関数、メソッド、ラムダをそのまま使えるため、最小構成でも実用的な設計が可能

Pythonicとは、“明示的に、変化を捉え、反応すること”。
Observerパターンはその反応性を、構造として整え、拡張可能にする知恵である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?