0
0

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(オブザーバー)パターンは、
あるオブジェクトの状態変化に応じて、依存する複数のオブジェクトへ自動的に通知・更新を行う設計パターンである。

GUIイベント、データバインディング、通知システムなど、**「誰かが変わったら誰かが反応する」**ような仕組みで重要な構造である。


1. なぜObserverが必要か?

❌ 依存先を直接呼び出すと結合度が高く、変更が困難

def update_temperature(new_temp):
    label.set_text(new_temp)
    logger.log(new_temp)

変更箇所が増えるたびに呼び出し元が肥大化・複雑化する


✅ 「通知を送る」ことだけに集中し、反応は登録されたオブザーバー側で自律的に行う

subject.attach(observer)
subject.notify()

依存関係を疎に保ち、柔軟な拡張と動的な反応が可能に


2. 基本構造

✅ Subject(通知元)

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

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

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

    def notify(self, *args, **kwargs):
        for observer in self._observers:
            observer.update(*args, **kwargs)

✅ Observer(通知先)

class Observer:
    def update(self, *args, **kwargs):
        raise NotImplementedError

✅ ConcreteObservers(具体的な反応)

class Logger(Observer):
    def update(self, value):
        print(f"[Logger] 新しい温度: {value}")

class Display(Observer):
    def update(self, value):
        print(f"[Display] 表示を更新: {value}")

✅ 使用例

subject = Subject()
subject.attach(Logger())
subject.attach(Display())

subject.notify(25)

出力:

[Logger] 新しい温度: 25  
[Display] 表示を更新: 25

3. Python的応用:関数ベースのObserver登録も可能

class Event:
    def __init__(self):
        self._handlers = []

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

    def fire(self, *args, **kwargs):
        for handler in self._handlers:
            handler(*args, **kwargs)

# 使用例
event = Event()
event.subscribe(lambda x: print(f"通知A: {x}"))
event.subscribe(lambda x: print(f"通知B: {x}"))
event.fire("変化しました")

シンプルな用途では関数を購読させる形でObserverを構成できる


4. 実務ユースケース

✅ GUIアプリケーションのイベントハンドリング

→ ボタンのクリック・入力変更に対してリアクティブに反応


✅ データ変更に応じた画面更新(MVVM, Flux)

ViewModelやStateに応じてViewが自動更新される


✅ 通知システム・アラート配信

→ センサー・監視ツールからの通知を複数の宛先に展開


✅ ゲームオブジェクトの監視と相互作用

→ あるオブジェクトの変化に対して他オブジェクトが連動して動く


5. よくある誤用と対策

❌ SubjectがObserverの中身に依存している

→ ✅ Observerはインターフェースとして設計し、Subjectは知らなくてよい


❌ 通知の順番や失敗が原因で状態不整合が起きる

→ ✅ 通知順や例外処理を設計時に明確にしておく


❌ 無限ループ・循環参照によるスタックオーバーフロー

→ ✅ 再帰的通知の設計に注意し、必要ならガードロジックを実装


結語

Observerパターンとは、“変化を見張り、反応する知性”を分離・再利用可能な構造で表現する技法である。

  • 状態の変化を他オブジェクトに伝播させ、疎結合でリアクティブな構造を構築
  • オブザーバー側が「何をするか」を自由に定義可能で、柔軟な連携が可能
  • Pythonでは関数ベース・クラスベースいずれも表現しやすく、動的な拡張性に優れる

Pythonicとは、“変化を直接操作するのではなく、通知によって委ねること”。
Observerパターンはその反応性を、設計の自律性として昇華する構造である。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?