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(仲介者)パターンは、
複数のオブジェクト間の直接的なやり取りを排除し、調停役となるオブジェクトを介して通信を管理する設計パターンである。

このパターンにより、クラス間の依存を最小化し、オブジェクト同士の関係性を疎結合に保つことができる。

特にUIコンポーネントやシステム間の調整、双方向通信の整理などで有効。


1. なぜMediatorが必要か?

❌ コンポーネント同士が直接やりとりすると複雑化

class Button:
    def click(self):
        text.hide()
        alert.show()

→ 各クラスが他クラスの実装を知っており、密結合・テスト困難・拡張性に乏しい


✅ Mediatorが全ての通信を調停

button.click()  # → mediator.notify(sender=button, event="click")

オブジェクト間の知識を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

✅ 具体的コンポーネント

class Button(Component):
    def click(self):
        print("Button clicked")
        self._mediator.notify(self, "click")

class TextBox(Component):
    def show(self):
        print("TextBox shown")

    def hide(self):
        print("TextBox hidden")

class Alert(Component):
    def show(self):
        print("Alert shown")

✅ 具体的Mediator

class AppMediator(Mediator):
    def __init__(self, button, text, alert):
        self.button = button
        self.text = text
        self.alert = alert

    def notify(self, sender, event):
        if sender == self.button and event == "click":
            self.text.hide()
            self.alert.show()

✅ 実行例

button = Button()
text = TextBox()
alert = Alert()

mediator = AppMediator(button, text, alert)
button.set_mediator(mediator)
text.set_mediator(mediator)
alert.set_mediator(mediator)

button.click()

3. Python的な工夫

✅ イベントベース設計への応用(Dictディスパッチ)

class Mediator:
    def __init__(self):
        self.handlers = {}

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

    def notify(self, event, *args):
        if event in self.handlers:
            self.handlers[event](*args)

mediator.register("submit", lambda: print("Submitted")) のように、柔軟なイベントハンドリングが可能


4. 実務ユースケース

✅ GUIアプリケーションの部品間調整

  • ボタン、チェックボックス、フォームが互いに依存せず、Mediatorで制御

✅ モジュール間連携の調整役として使用

  • マイクロサービス/ライブラリ間の連携制御をMediatorに任せる

✅ ゲーム開発におけるイベントルーティング

  • プレイヤー、NPC、UIなどが直接やりとりせず、EventHubとしてのMediatorで中継

5. よくある誤用と対策

❌ Mediatorが「神クラス」になる

→ ✅ Mediatorの役割を適切に分割し、責務が肥大化しないように制御(UI用、ビジネスロジック用など)


❌ 双方向通信がMediator外で発生してしまう

→ ✅ 必ず notify() 経由で通信するルールを徹底し、依存の逆流を防止


❌ MediatorをDIで注入せずコンポーネントに埋め込む

→ ✅ テスト性・再利用性を高めるため、明示的なMediatorインスタンスを設ける設計


結語

Mediatorパターンとは、“構造の複雑性を調整し、通信の流れを一元管理する”設計手法である。

  • コンポーネントの独立性を保ちながら、協調動作を可能にする
  • UIや複雑なビジネスロジックにおいて、相互作用を構造として記述可能
  • Pythonのシンプルな構文と組み合わせることで、柔らかく強固な設計を実現

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?