中介者模式

88 阅读3分钟

1. 简介

中介者模式(Mediator Pattern) 是一种行为设计模式,旨在通过将对象之间的通信集中化,减少对象之间的直接耦合,从而提高系统的可维护性和可扩展性。

2. 模式结构

classDiagram
    class Client {
        +main()
    }
    
    class Colleague {
        <<interface>>
        +send(message: str)
        +receive(message: str)
    }
    
    class Mediator {
        <<interface>>
        +register(colleague: Colleague)
        +send(from: Colleague)
    }
    
    class ConcreteColleague {
        -mediator: Mediator
        +send(message: str)
        +receive(message: str)
    }
    
    class ConcreteMediator {
        -colleagues: List[Colleague]
        +register(colleague: Colleague)
        +send(from: Colleague)
    }
    
    Colleague <|.. ConcreteColleague
    Mediator <|.. ConcreteMediator
    Client ..> ConcreteColleague
    Client ..> ConcreteMediator

在中介者模式中,存在一个中介者对象(也称为调停者或者调解者),它负责协调和处理系统中各个对象之间的交互。当一个对象需要与其他对象进行通信时,它不直接与其他对象通信,而是通过中介者对象进行通信。这样,所有的通信都集中在中介者对象中,而各个对象之间不再直接交互,从而减少了对象之间的耦合度。

中介者模式的主要参与者包括以下几个角色:

  • 抽象中介者(Mediator):  定义中介者的接口,用于各个具体同事对象之间的通信。
  • 具体中介者(Concrete Mediator):  实现抽象中介者接口,负责协调各个具体同事对象的交互关系,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。
  • 抽象同事类(Colleague):  定义同事类的接口,维护一个对中介者对象的引用,用于通信。
  • 具体同事类(Concrete Colleague):  实现抽象同事类接口,每个具体同事类只知道自己的行为,而不了解其他同事类的情况,因为它们都需要与中介者通信,通过中介者协调与其他同事对象的交互。
  • 客户端(Client): 负责调用具体中介者和具体同事类以完成所需功能。

3. 中介者模式的优缺点

中介者模式的优点包括:

  • 减少了对象之间的直接耦合,使系统更加灵活和可扩展。
  • 将系统的通信行为集中化,便于维护和管理。
  • 降低了系统的复杂度,提高了系统的可读性和可维护性。

然而,中介者模式也可能会引入单点故障,即中介者对象可能成为系统的瓶颈。因此,在设计中介者模式时需要注意权衡,避免过度集中化导致的性能问题。

4. 练习:【设计模式专题之中介者模式】16-简易聊天室

""" 
【设计模式专题之中介者模式】16-简易聊天室
时间限制:1.000S  空间限制:256MB
题目描述
小明正在设计一个简单的多人聊天室系统,有多个用户和一个聊天室中介者,用户通过中介者进行聊天,请你帮他完成这个系统的设计。
输入描述
第一行包括一个整数N,表示用户的数量(1 <= N <= 100) 第二行是N个用户,比如User1 User2 User3,用空格分隔 第三行开始,每行包含两个字符串,表示消息的发出者和消息内容,用空格分隔
输出描述
对于每个用户,输出一行,包含该用户收到的所有消息内容。
输入示例
3
User1 User2 User3
User1 Hello_All!
User2 Hi_User1!
User3 How_is_everyone?
输出示例
User2 received: Hello_All!
User3 received: Hello_All!
User1 received: Hi_User1!
User3 received: Hi_User1!
User1 received: How_is_everyone?
User2 received: How_is_everyone?
"""
from abc import ABC, abstractmethod


class User(ABC):
    @abstractmethod
    def send(self, message: str):
        raise NotImplemented
        
    @abstractmethod
    def receive(self, message: str):
        raise NotImplemented


class Mediator:
    @abstractmethod
    def register(self):
        raise NotImplemented
    
    @abstractmethod
    def send(self, message: str, to: User):
        raise NotImplemented
        
        
class ConcreteUser(User):
    def __init__(self, name: str, mediator: Mediator):
        self.name = name
        self.mediator = mediator
        
    def send(self, message: str):
        self.mediator.send(self, message)
        
    def receive(self, message: str):
        print(f"{self.name} received: {message}")
        
        
class ConcreteMediator(Mediator):
    def __init__(self):
        self.users: List[User] = []
        
    def register(self, user: User):
        self.users.append(user)
        
    def send(self, userFrom: User, message: str):
        for userTo in self.users:
            if userTo != userFrom:
                userTo.receive(message)
                
                
def client():
    mediator = ConcreteMediator()
    n = int(input())
    names = input().split()
    users = {name: ConcreteUser(name, mediator) for name in names}
    for _, user in users.items():
        mediator.register(user)
    for _ in range(n):
        name, message = input().split()
        user = users[name]
        user.send(message)
        
        
if __name__ == "__main__":
    client()

5. 参考文章