中介者模式
行为型模式
访问次数: 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