2
3

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で実装するMediatorパターン:依存を中央に集約し、関係性の爆発を防ぐ設計

Posted at

概要

Mediator(メディエーター)パターンは、
複数のオブジェクト同士が直接通信するのではなく、中央に調停者(Mediator)を配置して、
オブジェクト間の依存関係を1対1から1対多へと変換する構造的パターン
である。

この設計により、依存関係のスパゲッティ化を防ぎ、疎結合なコンポーネント同士を整然と接続することができる。


1. なぜMediatorが必要か?

❌ 各オブジェクトが他を知りすぎている(直接依存)

class A:
    def notify_b(self, b):
        b.do_something()

class B:
    def notify_c(self, c):
        c.do_other()

依存が連鎖し、変更が全体に波及する脆弱な設計


✅ 調停者(Mediator)がやり取りを一元管理

mediator.notify(sender=a, event="start")

オブジェクトはMediatorだけを知っていればよく、他のオブジェクトには非依存


2. 基本構造

✅ Mediatorインターフェース

class Mediator:
    def notify(self, sender, event):
        raise NotImplementedError

✅ コンポーネント側

class Component:
    def __init__(self, mediator=None):
        self._mediator = mediator

    def set_mediator(self, mediator):
        self._mediator = mediator

✅ 実装例:UIコンポーネントの調停

class Button(Component):
    def click(self):
        print("[Button] Clicked.")
        self._mediator.notify(self, "button_clicked")

class Dialog(Component):
    def show_message(self):
        print("[Dialog] Showing message...")

✅ ConcreteMediator(中央調停役)

class UIController(Mediator):
    def __init__(self, button, dialog):
        self.button = button
        self.dialog = dialog
        self.button.set_mediator(self)
        self.dialog.set_mediator(self)

    def notify(self, sender, event):
        if event == "button_clicked":
            self.dialog.show_message()

✅ 使用例

button = Button()
dialog = Dialog()
mediator = UIController(button, dialog)

button.click()
# Output:
# [Button] Clicked.
# [Dialog] Showing message...

3. Python的応用:イベント名とディスパッチ

class EventMediator:
    def __init__(self):
        self._handlers = {}

    def register(self, event, handler):
        self._handlers[event] = handler

    def notify(self, event, *args, **kwargs):
        if handler := self._handlers.get(event):
            handler(*args, **kwargs)
def on_login(user):
    print(f"{user} logged in")

mediator = EventMediator()
mediator.register("login", on_login)
mediator.notify("login", user="Alice")

イベントディスパッチャとしての応用も可能


4. 実務ユースケース

✅ GUIアプリケーション(MVC/Presenter)における中間調停

→ ボタン・フォーム・通知センターの仲介者としてUIControllerを設計


✅ チャットシステム、Pub/Sub基盤の調整層

→ ユーザー間メッセージの伝播をハブ的に集約


✅ ゲームのエンティティ間通信調整

→ プレイヤー・敵・環境が直接通信せずGameManagerが調整


✅ イベントバス/メッセージバス的設計

→ 状態遷移、ライフサイクル制御、非同期フローの管理にも応用


5. よくある誤用と対策

❌ Mediatorが神クラス化(全責務集中)

→ ✅ Mediatorは調停のみに責任を限定し、ロジックは各コンポーネントに


❌ すべてをMediator経由にしてしまう

→ ✅ 相互依存が発生する箇所のみに限定的にMediatorを導入


❌ コンポーネントがMediatorに強く依存

→ ✅ Mediator インターフェース経由で抽象化し、具象型への依存を排除


結語

Mediatorパターンとは、“複数のオブジェクト間の通信を集中管理することで、依存性の爆発を制御する構造設計”である。

  • 1対多構造への変換により、コードの拡張性と保守性を飛躍的に向上
  • 各コンポーネントの独立性を保ちつつ、連携の中心を明示的に定義
  • Pythonではオブジェクト参照とディスパッチ関数の活用により、柔軟かつ簡潔なMediator構築が可能

Pythonicとは、“疎結合で協調する”という設計思想であり、
Mediatorパターンはその仲介と制御の美学を、アーキテクチャに注ぎ込む技法である。

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?