中介者模式 (Mediator)
场景问题
问题案例
考虑一个聊天室系统,多个用户可以互相发送消息。如果每个用户都直接与其他用户通信,系统结构会非常复杂。
不用模式的解决方案
实现简化版本
最直接的做法是每个用户对象都持有其他所有用户的引用:
public class User {
private String name;
private List<User> users;
public User(String name) { this.name = name; }
public void setUsers(List<User> users) { this.users = users; }
public void send(String message) {
for (User u : users) {
if (!u.name.equals(this.name)) {
u.receive(message);
}
}
}
public void receive(String message) {
System.out.println(name + " 收到消息:" + message);
}
}
使用示例
User u1 = new User("张三");
User u2 = new User("李四");
User u3 = new User("王五");
List<User> users = Arrays.asList(u1, u2, u3);
u1.setUsers(users);
u2.setUsers(users);
u3.setUsers(users);
u1.send("大家好");
有何问题
- 用户之间耦合度高,扩展困难。
- 新增用户需修改所有用户的引用。
- 系统结构混乱,难以维护。
解决方案
中介者模式的定义
用一个中介对象来封装一系列对象之间的交互,使对象之间不再互相引用,降低耦合。
应用中介者模式的思路
- 定义中介者接口,具体中介者实现协调各对象。
- 各同事对象只与中介者交互,不直接引用其他对象。
- 新增同事对象无需修改其他对象。
中介者模式的结构
- Mediator:抽象中介者,定义统一接口。
- ConcreteMediator:具体中介者,实现协调逻辑。
- Colleague:抽象同事类。
- ConcreteColleagueA/B:具体同事类。
中介者模式的实现
// 抽象中介者
public interface Mediator {
void send(String message, Colleague colleague);
}
// 抽象同事
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) { this.mediator = mediator; }
public abstract void receive(String message);
public void send(String message) {
mediator.send(message, this);
}
}
// 具体同事
public class User extends Colleague {
private String name;
public User(String name, Mediator mediator) {
super(mediator);
this.name = name;
}
public void receive(String message) {
System.out.println(name + " 收到消息:" + message);
}
public String getName() { return name; }
}
// 具体中介者
public class ChatRoom implements Mediator {
private List<User> users = new ArrayList<>();
public void addUser(User user) { users.add(user); }
public void send(String message, Colleague sender) {
for (User u : users) {
if (u != sender) {
u.receive(message);
}
}
}
}
使用示例
public class Client {
public static void main(String[] args) {
ChatRoom chatRoom = new ChatRoom();
User u1 = new User("张三", chatRoom);
User u2 = new User("李四", chatRoom);
chatRoom.addUser(u1);
chatRoom.addUser(u2);
u1.send("大家好");
}
}
中介者重写示例
示例结构
示例代码
见上文“中介者模式的实现”部分。
模式讲解
中介者模式的功能
- 降低对象之间的耦合。
- 集中控制对象间的交互。
- 便于系统扩展和维护。
实现成接口
- 中介者和同事类通常定义为接口或抽象类。
使用工厂方法
- 可结合工厂方法模式,统一创建中介者和同事对象。
切换产品簇
- 可用于切换不同的中介者实现,如不同聊天室、消息路由等。