中介者模式(Mediator)
在软件开发中,当多个对象之间存在复杂的交互关系时,代码往往会变得错综复杂、耦合度极高,甚至牵一发而动全身,导致系统难以维护。而中介者模式的出现,正是为了解决这种“多对多对象通信”的问题。
我们希望系统中各组件之间解耦、职责单一,那么该如何做到呢?
答案就是使用 中介者模式(Mediator)。它可以将多个对象之间的“网状关系”转变成“一对多的星状结构”,由中介者来负责各对象之间的通信与协调。
中介者模式的定义
中介者模式(Mediator Pattern) 的定义是:用一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
模式结构
中介者模式由以下几个角色组成:
- 抽象中介者(Mediator):定义同事对象之间通信的接口。
- 具体中介者(ConcreteMediator):协调各同事对象,实现通信逻辑。
- 抽象同事类(Colleague):持有中介者对象的引用。
- 具体同事类(ConcreteColleague):实现自己的业务逻辑,在需要与其他同事交互时,通过中介者来进行通信。
实际应用场景
- 聊天室系统:用户之间不直接发送消息,而是通过聊天室中介发送与接收。
- GUI组件交互:例如点击按钮后通知文本框更新,组件之间通过窗口管理器(中介)通信。
- 飞机塔台指挥系统:飞机不直接与其他飞机沟通,而是通过塔台协调飞行。
示例
我们通过聊天室(ChatRoom)的实现来演示中介者模式。
抽象中介者
package com.yeliheng.mediator;
public interface ChatRoomMediator {
void sendMessage(String message, User user);
}
具体中介者
package com.yeliheng.mediator;
import java.util.ArrayList;
import java.util.List;
public class ChatRoom implements ChatRoomMediator {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
@Override
public void sendMessage(String message, User sender) {
for (User user : users) {
// 不发给自己
if (user != sender) {
user.receive(message);
}
}
}
}
抽象同事类
package com.yeliheng.mediator;
public abstract class User {
protected ChatRoomMediator mediator;
protected String name;
public User(ChatRoomMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void send(String message);
public abstract void receive(String message);
}
具体同事类
package com.yeliheng.mediator;
public class ConcreteUser extends User {
public ConcreteUser(ChatRoomMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
Main 运行测试
package com.yeliheng.mediator;
public class Main {
public static void main(String[] args) {
ChatRoomMediator chatRoom = new ChatRoom();
User user1 = new ConcreteUser(chatRoom, "小明");
User user2 = new ConcreteUser(chatRoom, "小红");
User user3 = new ConcreteUser(chatRoom, "小刚");
// 注册用户
((ChatRoom) chatRoom).addUser(user1);
((ChatRoom) chatRoom).addUser(user2);
((ChatRoom) chatRoom).addUser(user3);
user1.send("大家好,我是小明");
user2.send("你好,小明");
}
}
输出结果:
复制编辑
小明 发送消息: 大家好,我是小明
小红 收到消息: 大家好,我是小明
小刚 收到消息: 大家好,我是小明
小红 发送消息: 你好,小明
小明 收到消息: 你好,小明
小刚 收到消息: 你好,小明
小结
在本节中,我们通过聊天室的例子详细介绍了中介者模式的结构与实现。
中介者模式在系统中承担“调停者”的角色,让多个组件之间避免相互耦合,使得系统更加灵活、可维护。
中介者模式的优缺点
优点
- 降低对象之间的耦合度,使系统更易维护。
- 将对象之间复杂的交互逻辑集中到中介者中,便于管理。
- 符合单一职责原则与迪米特法则。
缺点
- 中介者会变得非常复杂,承担过多职责,容易演变成“上帝类”。
- 当同事对象较多时,中介者的逻辑可能会膨胀,导致维护困难。