Mediator Pattern 仲介模式

什麼情況適合使用 Mediator Pattern 仲介模式

仲介模式(Mediator Pattern)是一種行為型設計模式,用於協調多個物件之間的互動,並減少它們之間的直接通信。

這種模式的目的是將系統中的物件解耦,以改善其可維護性和擴展性。

以下是三個常見的 Mediator Pattern 實際應用範例:

  1. 聊天應用程序:聊天應用程序是一個常見的範例,其中多個用戶之間需要進行即時通信。在這種情況下,仲介者可以充當聊天室,負責接收來自不同用戶的消息並將它們傳送給適當的接收者。這樣,用戶之間不需要直接通信,而是透過仲介者進行消息交換。

  2. 飛航控制系統:在飛航控制系統中,多個飛行器(如飛機)需要協調它們的飛行路徑,以確保安全和順暢的飛行。一個仲介者可以跟蹤所有飛行器的位置和飛行計劃,並在需要時調整它們的路徑以避免碰撞或其他衝突。這有助於確保飛行器之間的協同工作,而無需它們之間的直接通信。

  3. 股票市場交易系統:在股票市場中,多個交易者進行股票交易,需要進行訂單匹配和執行。一個仲介者可以管理訂單簽署和匹配,確保買家和賣家之間的交易進行順暢。這樣,不同的交易者不需要直接了解彼此的訂單,而是透過仲介者處理交易的詳細信息。

這些情境突顯了仲介模式的作用,即協調多個物件之間的互動,使它們能夠獨立運作且不需要直接通信。這提高了系統的可維護性和可擴展性,同時確保互動的協同工作。

Mediator Pattern 仲介模式範例:Chat

from datetime import datetime

class ChatMediator:
    def __init__(self):
        self.participants = []  # 存儲所有參與者的列表
        self.groups = {}  # 存儲群組的字典
        self.events = {}  # 存儲參與者訂閱的事件的字典

    def add_participant(self, participant):
        self.participants.append(participant)  # 將參與者添加到參與者列表
        self.events[participant] = []  # 初始化事件列表

    def create_group(self, group_name, participants):
        self.groups[group_name] = participants  # 創建群組,將參與者添加到群組字典中

    def send_message(self, sender, message, group=None, recipient=None):
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        formatted_message = f'{timestamp} - {sender.name}: {message}'  # 格式化訊息,包括時間戳記和發送者

        if group:
            for participant in self.groups.get(group, []):
                if participant != sender:
                    participant.receive_message(formatted_message)  # 傳送群組訊息給群組中的參與者
        elif recipient:
            recipient.receive_message(formatted_message)  # 傳送私人訊息給特定接收者

    def subscribe_to_event(self, participant, event_type, callback):
        self.events[participant].append((event_type, callback))  # 註冊事件訂閱

    def notify_event(self, participant, event_type, data=None):
        for event, callback in self.events[participant]:
            if event == event_type:
                callback(data)  # 通知訂閱事件的回調函數
class Participant:
    def __init__(self, name, mediator):
        self.name = name  # 設定參與者的名稱
        self.mediator = mediator  # 設定參與者的中央仲介者

    def send(self, message, group=None, recipient=None):
        self.mediator.send_message(self, message, group, recipient)  # 發送訊息給中央仲介者

    def receive_message(self, message):
        print(message)  # 顯示接收到的訊息

    def join_group(self, group_name):
        self.mediator.groups[group_name].append(self)  # 加入指定的群組

    def leave_group(self, group_name):
        self.mediator.groups[group_name].remove(self)  # 離開指定的群組

    def subscribe_event(self, event_type, callback):
        self.mediator.subscribe_to_event(self, event_type, callback)  # 註冊事件訂閱

    def notify_event(self, event_type, data=None):
        self.mediator.notify_event(self, event_type, data)  # 通知事件
# 創建中央仲介者
mediator = ChatMediator()

# 創建聊天參與者
alice = Participant('Alice', mediator)
bob = Participant('Bob', mediator)
carol = Participant('Carol', mediator)

# 將聊天參與者註冊到中央仲介者
mediator.add_participant(alice)
mediator.add_participant(bob)
mediator.add_participant(carol)

# 創建群組
mediator.create_group('Group1', [alice, bob])
mediator.create_group('Group2', [alice, carol])

# 聊天參與者發送訊息到群組
alice.send('Hello, Group1!', group='Group1')
carol.send('Hi, Group2!', group='Group2')

# 私人訊息
alice.send('Hi, Bob!', recipient=bob)

# 通知事件
def on_new_message(data):
    print(f'Event: New Message - {data}')

bob.subscribe_event('New Message', on_new_message)
alice.send('New message for Bob!', recipient=bob)
## 輸出
2023-11-08 19:24:01 - Alice: Hello, Group1!
2023-11-08 19:24:01 - Carol: Hi, Group2!
2023-11-08 19:24:01 - Alice: Hi, Bob!
2023-11-08 19:24:01 - Alice: New message for Bob!

Class Diagram(類別圖)

classDiagram
  class ChatMediator {
    + participants: list
    + groups: dict
    + events: dict

    + add_participant(participant)
    + create_group(group_name, participants)
    + send_message(sender, message, group=None, recipient=None)
    + subscribe_to_event(participant, event_type, callback)
    + notify_event(participant, event_type, data=None)
  }

  class Participant {
    - name: str
    - mediator: ChatMediator

    + send(message, group=None, recipient=None)
    + receive_message(message)
    + join_group(group_name)
    + leave_group(group_name)
    + subscribe_event(event_type, callback)
    + notify_event(event_type, data=None)
  }

  ChatMediator "1" --> "0..*" Participant : contains