KnowHow

技術的なメモを中心にまとめます。
検索にて調べることができます。

Python基礎 オブジェクト指向19(Mediator) 振る舞いに関するデザインパターン

登録日 :2025/11/21 21:08
カテゴリ :Python基礎

(オブジェクトの種類)

関連しあうオブジェクト間のやり取りについて、仲介者となるオブジェクトに集約し、オブジェクトが直接やり取りすることを制限するパターン

直接のやり取りを制限することで、オブジェクトどうしの結びつきを弱める

- 

構成要素

Colleague

  • 仲介者とやり取りを行う抽象クラスまたはインターフェース
  • 仲介者と通信を行うためのAPIを定義
  • 内部に「仲介者」のオブジェクトを保持

ConcreteColleague

  • Colleagueを継承(実装)する子クラス
  • 仲介者と通信を行うための具体的な処理を実装

Mediator

  • 仲介者となる抽象クラスまたはインターフェース
  • Colleagueと通信を行って調整を行うためのAPIを定義

ConcreteMediator

  • Mediatorを継承(実装)する子クラス
  • 仲介を行う際の具体的な処理を実装

オブジェクト指向的要素

カプセル化を利用したパターン

  • ColleagueはMediatorを介してのみ別のColleagueとやり取りを行える

  • Colleague間のやり取りや関係性は隠ぺいされている(カプセル化している)

メリット・デメリット

メリット

  • オブジェクト同士のやり取りを集約し、理解しやすさと保守性を高めることができる
  • Colleagueオブジェクトの結びつきを弱くする

デメリット

  • Mediatorがすべてのオブジェクトに結合したゴッドクラスになる可能性がある

使い所

多くのオブジェクト同士が直接つながっている場合

  • オブジェクト間のつながりをMediatorに集約することで、理解しやすく、変更がしやすく、再利用性が高いプログラムになる

サンプル

複数のユーザがチャットでメッセージのやり取りを行う例

from __future__ import annotations
from abc import ABCMeta, abstractmethod


class Mediator(metaclass=ABCMeta):
    @abstractmethod
    def register_user(self, _user: User):
        pass

    @abstractmethod
    def send_message(self, _msg: str, _send_user: User):
        pass


class ChatRoom(Mediator):
    def __init__(self):
        self.__members = []

    def register_user(self, _user: User):
        self.__members.append(_user)

    def send_message(self, _msg: str, _send_user: User):
        for member in self.__members:
            if member != _send_user:
                member.receive(_msg)


class User(metaclass=ABCMeta):
    def __init__(self, _mediator: Mediator, _name: str):
        self._mediator = _mediator
        self._name = _name

    @abstractmethod
    def send(self, _msg:str):
        pass

    @abstractmethod
    def receive(self, _msg: str):
        pass


class ChatUser(User):
    def __init__(self, _mediator: Mediator, _name: str):
        super().__init__(_mediator, _name)

    def send(self, _msg:str):
        print(f'{self._name} -> send message')
        self._mediator.send_message(f"{_msg} from {self._name}", self)

    def receive(self, _msg: str):
        print(f'{self._name} -> receive message: {_msg}')


if __name__ == '__main__':
    chat_room = ChatRoom()

    yamada = ChatUser(chat_room, 'yamada')
    suzuki = ChatUser(chat_room, 'suzuki')
    tanaka = ChatUser(chat_room, 'tanaka')

    chat_room.register_user(yamada)
    chat_room.register_user(suzuki)
    chat_room.register_user(tanaka)

    yamada.send('Hello')
    suzuki.send('Hello')