中介
更新: 6/22/2025 字数: 0 字 时长: 0 分钟
定义
中介模式 (Mediator Pattern) 用一个中介对象来封装一系列对象之间的交互,使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。它通过减少对象间混乱的依赖关系来限制对象间的直接通信。
角色
- 中介者 (Mediator):定义对象间交互的接口
- 具体中介者 (Concrete Mediator):实现中介者接口,协调各同事对象
- 同事类 (Colleague):定义同事类的接口,维护中介者引用
- 具体同事类 (Concrete Colleague):实现同事类接口,通过中介者与其他同事通信
实现
聊天室中介
java
// 中介者接口
public interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者:聊天室
public class ChatRoom implements ChatMediator {
private List<User> users;
public ChatRoom() {
this.users = new ArrayList<>();
}
@Override
public void addUser(User user) {
this.users.add(user);
}
@Override
public void sendMessage(String msg, User user) {
for (User u : users) {
// 消息不发送给发送者
if (u != user) {
u.receive(msg);
}
}
}
}
// 同事类:用户
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name) {
this.mediator = med;
this.name = name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
// 具体同事类:普通用户
public class BasicUser extends User {
public BasicUser(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println(name + " 发送:" + msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(name + " 收到:" + msg);
}
}
// 具体同事类:管理员
public class AdminUser extends User {
public AdminUser(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println("【管理员】" + name + " 广播:" + msg);
mediator.sendMessage("【公告】" + msg, this);
}
@Override
public void receive(String msg) {
System.out.println("【管理员】" + name + " 收到:" + msg);
}
}
// 客户端使用
public class ChatDemo {
public static void main(String[] args) {
ChatMediator mediator = new ChatRoom();
User user1 = new BasicUser(mediator, "张三");
User user2 = new BasicUser(mediator, "李四");
User user3 = new BasicUser(mediator, "王五");
User admin = new AdminUser(mediator, "管理员");
mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);
mediator.addUser(admin);
user1.send("大家好!");
admin.send("欢迎新用户加入!");
user2.send("谢谢管理员!");
}
}
机场交通控制中介
java
// 飞机接口
public interface Aircraft {
void requestLanding();
void landingComplete();
void requestTakeoff();
void takeoffComplete();
}
// 具体飞机
public class CommercialAircraft implements Aircraft {
private String flightNumber;
private AirTrafficControl atc;
public CommercialAircraft(String flightNumber, AirTrafficControl atc) {
this.flightNumber = flightNumber;
this.atc = atc;
}
@Override
public void requestLanding() {
System.out.println(flightNumber + " 请求降落");
atc.requestLanding(this);
}
@Override
public void landingComplete() {
System.out.println(flightNumber + " 降落完成");
atc.notifyLandingComplete(this);
}
@Override
public void requestTakeoff() {
System.out.println(flightNumber + " 请求起飞");
atc.requestTakeoff(this);
}
@Override
public void takeoffComplete() {
System.out.println(flightNumber + " 起飞完成");
atc.notifyTakeoffComplete(this);
}
}
// 中介者:空中交通管制
public interface AirTrafficControl {
void requestLanding(Aircraft aircraft);
void notifyLandingComplete(Aircraft aircraft);
void requestTakeoff(Aircraft aircraft);
void notifyTakeoffComplete(Aircraft aircraft);
}
// 具体中介者
public class ControlTower implements AirTrafficControl {
private Queue<Aircraft> landingQueue = new LinkedList<>();
private Queue<Aircraft> takeoffQueue = new LinkedList<>();
private boolean runwayAvailable = true;
@Override
public void requestLanding(Aircraft aircraft) {
if (runwayAvailable) {
System.out.println("允许 " + aircraft + " 降落");
runwayAvailable = false;
} else {
System.out.println("跑道占用," + aircraft + " 加入降落队列");
landingQueue.add(aircraft);
}
}
@Override
public void notifyLandingComplete(Aircraft aircraft) {
System.out.println(aircraft + " 已降落,跑道空闲");
runwayAvailable = true;
processNext();
}
@Override
public void requestTakeoff(Aircraft aircraft) {
if (runwayAvailable) {
System.out.println("允许 " + aircraft + " 起飞");
runwayAvailable = false;
} else {
System.out.println("跑道占用," + aircraft + " 加入起飞队列");
takeoffQueue.add(aircraft);
}
}
@Override
public void notifyTakeoffComplete(Aircraft aircraft) {
System.out.println(aircraft + " 已起飞,跑道空闲");
runwayAvailable = true;
processNext();
}
private void processNext() {
// 优先处理降落请求
if (!landingQueue.isEmpty()) {
Aircraft next = landingQueue.poll();
System.out.println("通知 " + next + " 降落");
next.requestLanding();
} else if (!takeoffQueue.isEmpty()) {
Aircraft next = takeoffQueue.poll();
System.out.println("通知 " + next + " 起飞");
next.requestTakeoff();
}
}
}
// 使用示例
public class AirportDemo {
public static void main(String[] args) {
AirTrafficControl tower = new ControlTower();
Aircraft flight1 = new CommercialAircraft("CA123", tower);
Aircraft flight2 = new CommercialAircraft("UA456", tower);
Aircraft flight3 = new CommercialAircraft("DL789", tower);
// 飞行活动
flight1.requestLanding();
flight2.requestLanding();
flight1.landingComplete();
flight3.requestTakeoff();
flight2.landingComplete();
flight3.takeoffComplete();
}
}
优缺点
优点:
- 减少类间依赖(从网状到星形)
- 简化对象协议
- 集中控制交互逻辑
- 提高系统灵活性
- 符合迪米特法则
- 便于扩展新同事类
缺点:
- 中介者可能变得复杂臃肿
- 可能成为系统性能瓶颈
- 过度集中化风险
- 增加系统复杂度
- 调试困难(交互逻辑集中)
应用场景
- 聊天应用程序
- 空中交通管制系统
- GUI 组件交互
- 分布式系统协调
- 工作流管理系统
- 多玩家游戏架构
- 企业应用集成
与其他模式的关系
- 与观察者模式:常结合使用,中介者作为观察对象
- 与门面模式:门面封装子系统,中介者协调同事
- 与代理模式:中介者可代理同事间通信
- 与命令模式:中介者发送命令给同事
- 与状态模式:中介者状态影响协调行为
- 与责任链模式:中介者替代责任链
JDK 中的中介模式
- Java Message Service (JMS)
- Java Executor 框架
- Java Timer 类
- Java Swing 中的 Mediator
- Spring 框架的事件机制
- Java EE Contexts and Dependency Injection (CDI)
- Java 并发工具包(java.util.concurrent)
注意事项
- 避免创建"上帝对象"
- 合理划分中介者职责
- 考虑中介者性能优化
- 设计清晰的通信协议
- 处理中介者单点故障
- 支持中介者链式处理
- 合理设计同事类接口