中介者模式

行为型模式

访问次数: 11

中介者模式用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

类图
classDiagram
    class Mediator {
        <<interface>>
        +notify(sender: Colleague, event: String)
    }
    class ConcreteMediator {
        -colleague1: Colleague1
        -colleague2: Colleague2
        +notify(sender: Colleague, event: String)
    }
    class Colleague {
        <<abstract>>
        #mediator: Mediator
        +setMediator(mediator: Mediator)
    }
    class Colleague1 {
        +doSomething()
    }
    class Colleague2 {
        +doSomething()
    }
    Mediator <|-- ConcreteMediator
    Colleague <|-- Colleague1
    Colleague <|-- Colleague2
    ConcreteMediator --> Colleague1
    ConcreteMediator --> Colleague2
    Colleague --> Mediator
源代码示例
// 中介者接口
interface Mediator {
    void notify(Colleague sender, String event);
}

// 抽象同事类
abstract class Colleague {
    protected Mediator mediator;
    
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }
}

// 具体同事类1
class Colleague1 extends Colleague {
    public void doSomething() {
        System.out.println("Colleague1 doSomething");
        mediator.notify(this, "event1");
    }
}

// 具体同事类2
class Colleague2 extends Colleague {
    public void doSomething() {
        System.out.println("Colleague2 doSomething");
        mediator.notify(this, "event2");
    }
}

// 具体中介者
class ConcreteMediator implements Mediator {
    private Colleague1 colleague1;
    private Colleague2 colleague2;
    
    public void setColleague1(Colleague1 colleague1) {
        this.colleague1 = colleague1;
    }
    
    public void setColleague2(Colleague2 colleague2) {
        this.colleague2 = colleague2;
    }
    
    @Override
    public void notify(Colleague sender, String event) {
        if (sender == colleague1) {
            System.out.println("Mediator handling event from Colleague1: " + event);
            colleague2.doSomething();
        } else if (sender == colleague2) {
            System.out.println("Mediator handling event from Colleague2: " + event);
            colleague1.doSomething();
        }
    }
}
# Python代码待添加
应用场景
当多个对象之间存在复杂的相互引用关系,导致系统结构混乱时。应用场景包括: 1)聊天室系统中,多个用户之间的消息传递通过中介者(聊天室服务器)进行协调 2)MVC架构中的控制器,协调模型和视图之间的交互 3)对话框组件,协调多个UI控件之间的交互和状态同步 4)事件总线系统,协调多个事件发布者和订阅者之间的通信 5)工作流引擎,协调多个工作流节点之间的执行顺序和数据传递 6)分布式系统中的协调器,协调多个服务节点之间的交互和状态同步
精选场景详解 —— 聊天室:用户消息经服务器中转
问题背景

若每个用户对象直接持有其他所有用户引用,N 人聊天的关系是 O(N²),结构混乱,也难做广播/禁言等统一策略。

模式如何解决
选用中介者:ChatRoomMediator 协调 Colleague(User)。用户只与中介者通信:send 时交给中介者,由中介者转发给其他用户或按房间规则过滤。 效果:把网状依赖变成星型依赖,交互规则集中在中介者,便于增加审计、敏感词过滤、房间管理。 MVC 中的 Controller、前端 EventBus 也常体现中介者思想。注意中介者本身可能变「上帝对象」,职责要克制。
场景模型(角色映射)

将模式中的抽象角色映射到该业务领域的具体类:

classDiagram
    class ChatMediator {
        <<interface>>
        +register(user: User)
        +send(from: User, message: String)
    }
    class ChatRoom {
        -users: List~User~
        +register(user: User)
        +send(from: User, message: String)
    }
    class User {
        <<abstract>>
        #mediator: ChatMediator
        #name: String
        +send(message: String)
        +receive(from: String, message: String)
    }
    class ChatUser {
        +send(message: String)
        +receive(from: String, message: String)
    }
    ChatMediator <|.. ChatRoom
    User <|-- ChatUser
    ChatRoom --> User
    User --> ChatMediator