概要
Mediator(メディエーター)パターンは、
複数のオブジェクト間の複雑なやり取りを**“調停者”としての中央オブジェクトに一元化する設計パターン**である。
個々のコンポーネントが互いに直接参照し合うのではなく、Mediatorを介して通信することで、オブジェクト同士の依存関係を緩和(疎結合)できる。
1. なぜMediatorが必要か?
❌ 複数オブジェクトが相互に依存しすぎて、修正コストが爆発する
class Button:
def click(self):
textbox.hide()
dialog.open()
class TextBox:
def input(self):
button.disable()
→ ロジックが絡み合い、変更に対する影響範囲が広がる
✅ 各コンポーネントはMediatorに通知し、処理はMediatorに集約
button.click() → mediator.notify(sender, "click")
→ イベントの流れが一元化され、個別の依存を解消
2. 基本構造
✅ Mediatorインターフェース
class Mediator:
def notify(self, sender, event):
raise NotImplementedError
✅ ConcreteMediator(具体的調停者)
class DialogMediator(Mediator):
def __init__(self):
self.button = None
self.textbox = None
def notify(self, sender, event):
if sender == self.button and event == "click":
print("→ ボタンが押された。テキストボックスを隠す")
self.textbox.hide()
elif sender == self.textbox and event == "input":
print("→ テキスト入力あり。ボタンを有効に")
self.button.enable()
✅ 各コンポーネント
class Button:
def __init__(self, mediator: Mediator):
self.mediator = mediator
def click(self):
print("[UI] ボタンがクリックされた")
self.mediator.notify(self, "click")
def enable(self):
print("[UI] ボタンが有効になった")
class TextBox:
def __init__(self, mediator: Mediator):
self.mediator = mediator
def input(self):
print("[UI] テキスト入力された")
self.mediator.notify(self, "input")
def hide(self):
print("[UI] テキストボックスを非表示にした")
✅ 使用例
mediator = DialogMediator()
button = Button(mediator)
textbox = TextBox(mediator)
mediator.button = button
mediator.textbox = textbox
button.click()
textbox.input()
出力:
[UI] ボタンがクリックされた
→ ボタンが押された。テキストボックスを隠す
[UI] テキストボックスを非表示にした
[UI] テキスト入力された
→ テキスト入力あり。ボタンを有効に
[UI] ボタンが有効になった
3. Python的応用:イベントベースの通知スタイル
class EventMediator:
def __init__(self):
self.handlers = {}
def register(self, event, handler):
self.handlers.setdefault(event, []).append(handler)
def notify(self, event, *args, **kwargs):
for handler in self.handlers.get(event, []):
handler(*args, **kwargs)
mediator = EventMediator()
mediator.register("message_sent", lambda msg: print(f"ログ: {msg}"))
mediator.notify("message_sent", "Hello World")
→ イベントディスパッチャとしての柔軟なMediator実装も可能
4. 実務ユースケース
✅ UIフォーム内のコンポーネント連携制御
→ ボタン、入力欄、バリデーションの状態制御をMediatorに集約
✅ チャット・ゲーム内オブジェクト通信のハブ
→ 各プレイヤーやNPC間の通信を中央ルータで調整
✅ モジュール間の疎結合イベント伝達
→ ログ記録、バリデーション、通知などクロスカット処理の一元化
✅ マイクロサービス間通信のオーケストレーション
→ 複数サービスの連携を1つのハブで統括・調停
5. よくある誤用と対策
❌ Mediatorがすべてのロジックを抱え込み、巨大化する
→ ✅ 責務を分割し、複数のMediatorに委任する
❌ Mediatorが抽象化されず実装に依存しすぎる
→ ✅ インターフェースやイベント名で疎結合に設計
❌ 双方向依存が発生し、調停の意味がなくなる
→ ✅ Mediatorからのみ通知・制御させ、依存方向を一方通行に
結語
Mediatorパターンとは、“複雑な関係性を一箇所に集約し、秩序ある調整を可能にする設計”である。
- オブジェクト同士の直接依存を断ち、拡張性とテスト性を高める
- イベント通知・状態変化・ロジック調整を一元管理しやすくする
- Pythonでは動的ディスパッチや辞書ベースで、柔軟に構築可能
Pythonicとは、“話す相手を限定せず、通訳を介して全体を制御すること”。
Mediatorパターンはその会話の知性を、構造の調停者として明示する技法である。