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で実装するMediatorパターン:複雑な相互依存を一元的に調停する

Posted at

概要

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パターンはその会話の知性を、構造の調停者として明示する技法である。

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?