中介者模式:复杂交互的协调者
摘要
中介者模式(Mediator Pattern)是行为型设计模式中的"交互控制器",它通过封装一组对象之间的交互来降低对象之间的直接耦合。本文将深入解析中介者模式的核心概念、实现方式、应用场景及高级变体,通过丰富的Java代码示例展示如何构建集中式交互系统,并分析其与观察者模式、外观模式的区别与适用场景。
一、中介者模式核心思想
中介者模式的核心是集中控制对象交互,具有以下关键特征:
- 交互中心化:所有交互通过中介者进行
- 解耦对象:对象间不直接相互引用
- 简化通信:将多对多关系简化为一对多
- 控制集中:交互逻辑集中在中介者中
适用场景:
- 对象间存在复杂网状引用关系
- 对象间通信方式需要灵活变更
- 需要集中管理对象间的交互规则
- 对象需要重用但交互行为不可重用
二、中介者模式结构解析
UML类图示意
[Mediator] <|-- [ConcreteMediator]
[Colleague] <|-- [ConcreteColleagueA]
[Colleague] <|-- [ConcreteColleagueB]
[ConcreteColleagueA] --> [Mediator]
[ConcreteColleagueB] --> [Mediator]
核心组件角色
| 角色 |
职责 |
典型实现 |
| Mediator |
中介者接口 |
定义同事对象通信接口 |
| ConcreteMediator |
具体中介者 |
实现协调逻辑,维护同事引用 |
| Colleague |
同事类 |
知道中介者,通过中介者通信 |
| ConcreteColleague |
具体同事 |
实现业务功能,不直接引用其他同事 |
三、基础实现:聊天室案例
// 中介者接口
interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者:聊天室实现
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 : this.users) {
// 消息不发送给自己
if (u != user) {
u.receive(msg);
}
}
}
}
// 同事类:用户
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);
}
// 具体同事类:普通用户
class BasicUser extends User {
public BasicUser(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println(name + " sends: " + msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(name + " receives: " + msg);
}
}
// 具体同事类:VIP用户
class VIPUser extends User {
public VIPUser(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println(name + " sends [VIP]: " + msg);
mediator.sendMessage("[VIP] " + msg, this);
}
@Override
public void receive(String msg) {
System.out.println(name + " receives [VIP priority]: " + msg);
}
}
// 客户端使用
public class ChatRoomDemo {
public static void main(String[] args) {
ChatMediator mediator = new ChatRoom();
User john = new BasicUser(mediator, "John");
User jane = new BasicUser(mediator, "Jane");
User admin = new VIPUser(mediator, "Admin");
mediator.addUser(john);
mediator.addUser(jane);
mediator.addUser(admin);
john.send("Hi everyone");
admin.send("Welcome to the chat!");
}
}
四、高级应用:航空交通管制系统
1. 飞机与塔台交互
// 中介者接口
interface AirTrafficControl {
void registerAircraft(Aircraft aircraft);
void sendWarning(String message, Aircraft sender);
void requestLandingClearance(Aircraft aircraft);
void reportPosition(Aircraft aircraft, Position position);
}
// 具体中介者:控制塔
class ControlTower implements AirTrafficControl {
private List<Aircraft> aircrafts = new ArrayList<>();
private Map<Position, Aircraft> positionMap = new HashMap<>();
@Override
public void registerAircraft(Aircraft aircraft) {
aircrafts.add(aircraft);
}
@Override
public void sendWarning(String message, Aircraft sender) {
aircrafts.stream()
.filter(a -> a != sender)
.forEach(a -> a.receiveWarning(message));
}
@Override
public void requestLandingClearance(Aircraft aircraft) {
boolean runwayClear = positionMap.values().stream()
.noneMatch(a -> a.getStatus() == AircraftStatus.LANDING);
if (runwayClear) {
aircraft.receiveClearance(true);
aircraft.setStatus(AircraftStatus.LANDING);
} else {
aircraft.receiveClearance(false);
System.out.println("Runway occupied - please wait");
}
}
@Override
public void reportPosition(Aircraft aircraft, Position position) {
positionMap.put(position, aircraft);
checkForCollisions(aircraft, position);
}
private void checkForCollisions(Aircraft aircraft, Position position) {
positionMap.forEach((pos, a) -> {
if (a != aircraft && pos.distanceTo(position) < 5) {
sendWarning("Collision alert with " + a.getId(), aircraft);
}
});
}
}
// 同事类:飞机
class Aircraft {
private AirTrafficControl atc;
private String id;
private AircraftStatus status;
public Aircraft(AirTrafficControl atc, String id) {
this.atc = atc;
this.id = id;
this.status = AircraftStatus.IN_FLIGHT;
atc.registerAircraft(this);
}
public void sendWarning(String message) {
atc.sendWarning(message, this);
}
public void requestLandingClearance() {
atc.requestLandingClearance(this);
}
public void reportPosition(Position position) {
atc.reportPosition(this, position);
}
public void receiveWarning(String message) {
System.out.println(id + " received warning: " + message);
}
public void receiveClearance(boolean granted) {
System.out.println(id + " landing clearance: " + (granted ? "GRANTED" : "DENIED"));
}
public String getId() {
return id;
}
public AircraftStatus getStatus() {
return status;
}
public void setStatus(AircraftStatus status) {
this.status = status;
}
}
// 辅助类
class Position {
private double x, y, altitude;
public Position(double x, double y, double altitude) {
this.x = x;
this.y = y;
this.altitude = altitude;
}
public double distanceTo(Position other) {
return Math.sqrt(
Math.pow(x - other.x, 2) +
Math.pow(y - other.y, 2) +
Math.pow(altitude - other.altitude, 2)
);
}
}
enum AircraftStatus {
IN_FLIGHT, LANDING, ON_GROUND
}
// 使用示例
public class ATCSystem {
public static void main(String[] args) {
AirTrafficControl atc = new ControlTower();
Aircraft flight1 = new Aircraft(atc, "FL123");
Aircraft flight2 = new Aircraft(atc, "BA456");
flight1.reportPosition(new Position(10, 20, 10000));
flight2.reportPosition(new Position(12, 22, 10050));
flight1.requestLandingClearance();
flight2.requestLandingClearance();
}
}
2. 微服务协调中介者
// 微服务中介者
class MicroservicesMediator {
private Map<String, Microservice> services = new HashMap<>();
private CircuitBreaker circuitBreaker = new CircuitBreaker();
public void registerService(Microservice service) {
services.put(service.getName(), service);
}
public Object forwardRequest(String serviceName, String request) {
if (!circuitBreaker.isServiceAvailable(serviceName)) {
return fallbackResponse(serviceName);
}
Microservice service = services.get(serviceName);
if (service == null) {
throw new IllegalArgumentException("Unknown service: " + serviceName);
}
try {
Object response = service.handleRequest(request);
circuitBreaker.recordSuccess(serviceName);
return response;
} catch (Exception e) {
circuitBreaker.recordFailure(serviceName);
return fallbackResponse(serviceName);
}
}
private Object fallbackResponse(String serviceName) {
// 返回缓存或默认响应
return "Service " + serviceName + " is currently unavailable";
}
public void broadcastEvent(String eventName, Object eventData) {
services.values().forEach(service -> {
if (service.getSubscribedEvents().contains(eventName)) {
service.handleEvent(eventName, eventData);
}
});
}
}
// 微服务基类
abstract class Microservice {
private MicroservicesMediator mediator;
private String name;
private Set<String> subscribedEvents = new HashSet<>();
public Microservice(MicroservicesMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
mediator.registerService(this);
}
public String getName() {
return name;
}
public Set<String> getSubscribedEvents() {
return Collections.unmodifiableSet(subscribedEvents);
}
public void subscribeToEvent(String eventName) {
subscribedEvents.add(eventName);
}
public Object callService(String serviceName, String request) {
return mediator.forwardRequest(serviceName, request);
}
public void publishEvent(String eventName, Object eventData) {
mediator.broadcastEvent(eventName, eventData);
}
public abstract Object handleRequest(String request);
public abstract void handleEvent(String eventName, Object eventData);
}
// 断路器模式实现
class CircuitBreaker {
private Map<String, ServiceState> serviceStates = new HashMap<>();
private static final int FAILURE_THRESHOLD = 3;
private static final long RETRY_TIMEOUT = 30000; // 30秒
public boolean isServiceAvailable(String serviceName) {
ServiceState state = serviceStates.get(serviceName);
if (state == null) {
return true;
}
if (state.status == Status.OPEN) {
long now = System.currentTimeMillis();
if (now - state.lastFailureTime > RETRY_TIMEOUT) {
state.status = Status.HALF_OPEN;
return true;
}
return false;
}
return true;
}
public void recordSuccess(String serviceName) {
ServiceState state = serviceStates.get(serviceName);
if (state != null && state.status == Status.HALF_OPEN) {
state.status = Status.CLOSED;
state.failureCount = 0;
}
}
public void recordFailure(String serviceName) {
ServiceState state = serviceStates.computeIfAbsent(
serviceName,
k -> new ServiceState()
);
state.failureCount++;
state.lastFailureTime = System.currentTimeMillis();
if (state.failureCount >= FAILURE_THRESHOLD) {
state.status = Status.OPEN;
}
}
private static class ServiceState {
Status status = Status.CLOSED;
int failureCount = 0;
long lastFailureTime = 0;
}
private enum Status {
CLOSED, OPEN, HALF_OPEN
}
}
// 使用示例
public class MicroservicesDemo {
public static void main(String[] args) {
MicroservicesMediator mediator = new MicroservicesMediator();
Microservice orderService = new OrderService(mediator);
Microservice paymentService = new PaymentService(mediator);
// 服务间调用
Object result = orderService.callService("PaymentService", "processPayment");
System.out.println("Payment result: " + result);
// 事件发布
orderService.publishEvent("OrderCreated", "Order123");
}
}
class OrderService extends Microservice {
public OrderService(MicroservicesMediator mediator) {
super(mediator, "OrderService");
subscribeToEvent("PaymentProcessed");
}
@Override
public Object handleRequest(String request) {
return "Order processed: " + request;
}
@Override
public void handleEvent(String eventName, Object eventData) {
System.out.println("OrderService received event: " + eventName + " - " + eventData);
}
}
class PaymentService extends Microservice {
public PaymentService(MicroservicesMediator mediator) {
super(mediator, "PaymentService");
subscribeToEvent("OrderCreated");
}
@Override
public Object handleRequest(String request) {
return "Payment processed: " + request;
}
@Override
public void handleEvent(String eventName, Object eventData) {
System.out.println("PaymentService received event: " + eventName + " - " + eventData);
}
}
五、中介者模式优缺点分析
优点:
| 优点 |
说明 |
| 降低耦合 |
对象间不直接相互引用 |
| 简化交互 |
将多对多关系简化为一对多 |
| 集中控制 |
交互规则集中管理 |
| 复用对象 |
对象可独立于交互方式复用 |
| 扩展灵活 |
新增交互规则不影响现有对象 |
缺点:
| 缺点 |
说明 |
| 复杂性转移 |
中介者可能变得过于复杂 |
| 单点故障 |
中介者故障影响整个系统 |
| 性能瓶颈 |
所有交互通过中介者可能影响性能 |
| 过度设计 |
简单系统使用中介者可能不必要 |
六、中介者模式与其他模式对比
中介者模式 vs 观察者模式
| 维度 |
中介者模式 |
观察者模式 |
| 通信方向 |
双向通信 |
单向通知 |
| 耦合度 |
对象知道中介者 |
观察者不知道被观察者 |
| 控制中心 |
集中控制交互 |
分布式事件处理 |
| 适用场景 |
复杂交互协调 |
状态变化通知 |
中介者模式 vs 外观模式
| 维度 |
中介者模式 |
外观模式 |
| 目的 |
协调对象间交互 |
简化子系统接口 |
| 参与者 |
同级对象间交互 |
为高层提供统一接口 |
| 知晓度 |
对象知道中介者 |
子系统不知道外观 |
| 复杂性 |
处理同级对象复杂交互 |
隐藏子系统复杂性 |
七、中介者模式最佳实践
1. 中介者与命令模式结合
// 命令接口
interface Command {
void execute();
}
// 中介者扩展命令支持
class CommandMediator {
private Map<String, Command> commands = new HashMap<>();
private List<Command> history = new ArrayList<>();
public void registerCommand(String name, Command command) {
commands.put(name, command);
}
public void executeCommand(String name) {
Command command = commands.get(name);
if (command != null) {
command.execute();
history.add(command);
}
}
public void undoLastCommand() {
if (!history.isEmpty()) {
Command command = history.remove(history.size() - 1);
System.out.println("Undoing command: " + command.getClass().getSimpleName());
}
}
}
// 具体命令
class SaveCommand implements Command {
private Document document;
public SaveCommand(Document document) {
this.document = document;
}
@Override
public void execute() {
document.save();
}
}
// 使用示例
Document doc = new Document();
CommandMediator mediator = new CommandMediator();
mediator.registerCommand("save", new SaveCommand(doc));
mediator.executeCommand("save");
2. 中介者与状态模式结合
// 状态感知中介者
class StatefulMediator {
private Map<Object, State> objectStates = new HashMap<>();
public void setState(Object obj, State state) {
objectStates.put(obj, state);
}
public void mediateInteraction(Object obj1, Object obj2) {
State state1 = objectStates.get(obj1);
State state2 = objectStates.get(obj2);
if (state1 != null && state2 != null) {
// 根据状态决定交互方式
if (state1 == State.ACTIVE && state2 == State.ACTIVE) {
System.out.println("Both objects active - standard interaction");
} else if (state1 == State.BLOCKED || state2 == State.BLOCKED) {
System.out.println("Blocked state detected - limited interaction");
}
}
}
}
enum State {
ACTIVE, INACTIVE, BLOCKED
}
3. 中介者与依赖注入
// 使用Spring框架的中介者
@Component
class SystemMediator {
private final Map<String, SystemComponent> components = new HashMap<>();
@Autowired
public SystemMediator(List<SystemComponent> allComponents) {
allComponents.forEach(component -> {
components.put(component.getName(), component);
component.setMediator(this);
});
}
public void sendMessage(String componentName, String message) {
SystemComponent component = components.get(componentName);
if (component != null) {
component.receiveMessage(message);
}
}
}
@Component
class NetworkComponent implements SystemComponent {
private final String name = "Network";
private SystemMediator mediator;
public void setMediator(SystemMediator mediator) {
this.mediator = mediator;
}
public void broadcast(String message) {
mediator.sendMessage("All", message);
}
public void receiveMessage(String message) {
System.out.println(name + " received: " + message);
}
public String getName() {
return name;
}
}
八、中介者模式在开源框架中的应用
Spring MVC中的DispatcherServlet
// DispatcherServlet作为HTTP请求的中介者
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public String listUsers(Model model) {
model.addAttribute("users", userService.findAll());
return "users/list";
}
}
// DispatcherServlet协调Controller、ViewResolver等组件
Java Message Service (JMS)
// JMS作为消息中介者
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("Orders");
MessageProducer producer = session.createProducer(queue);
MessageConsumer consumer = session.createConsumer(queue);
// 生产者发送消息
TextMessage message = session.createTextMessage("New order");
producer.send(message);
// 消费者接收消息
Message received = consumer.receive();
if (received instanceof TextMessage) {
System.out.println("Received: " + ((TextMessage) received).getText());
}
九、高级应用:分布式中介者
1. 基于消息队列的分布式中介者
// 分布式中介者接口
interface DistributedMediator {
void registerService(String serviceId, ServiceEndpoint endpoint);
void sendCommand(String serviceId, Command command);
void broadcastEvent(Event event);
}
// RabbitMQ实现
class RabbitMQMediator implements DistributedMediator {
private final ConnectionFactory factory;
private final Map<String, String> serviceQueues = new ConcurrentHashMap<>();
public RabbitMQMediator(String host) {
this.factory = new ConnectionFactory();
this.factory.setHost(host);
}
@Override
public void registerService(String serviceId, ServiceEndpoint endpoint) {
try (Connection conn = factory.newConnection();
Channel channel = conn.createChannel()) {
String queueName = "service." + serviceId;
channel.queueDeclare(queueName, false, false, false, null);
serviceQueues.put(serviceId, queueName);
// 启动消费者线程
new Thread(() -> consumeMessages(serviceId, endpoint)).start();
} catch (Exception e) {
throw new RuntimeException("Registration failed", e);
}
}
private void consumeMessages(String serviceId, ServiceEndpoint endpoint) {
try (Connection conn = factory.newConnection();
Channel channel = conn.createChannel()) {
String queueName = serviceQueues.get(serviceId);
channel.basicConsume(queueName, true, (consumerTag, delivery) -> {
Command command = deserializeCommand(delivery.getBody());
endpoint.handleCommand(command);
}, consumerTag -> {});
} catch (Exception e) {
System.err.println("Consumer error: " + e.getMessage());
}
}
@Override
public void sendCommand(String serviceId, Command command) {
// 实现命令发送逻辑...
}
@Override
public void broadcastEvent(Event event) {
// 实现事件广播逻辑...
}
}
2. 微服务API网关
// API网关作为微服务中介者
@RestController
@RequestMapping("/api")
public class ApiGateway {
@Autowired
private UserServiceClient userService;
@Autowired
private OrderServiceClient orderService;
@GetMapping("/user/{userId}/orders")
public ResponseEntity<List<Order>> getUserOrders(@PathVariable String userId) {
// 验证用户存在
User user = userService.getUser(userId);
if (user == null) {
return ResponseEntity.notFound().build();
}
// 获取用户订单
List<Order> orders = orderService.getUserOrders(userId);
return ResponseEntity.ok(orders);
}
}
十、中介者模式未来发展趋势
新兴应用方向:
- 服务网格:服务间通信的中介层
- 事件驱动架构:复杂事件处理中介
- 物联网平台:设备间交互协调
- 区块链智能合约:合约间交互中介
- AI系统集成:协调多个AI模型交互
响应式中介者模式
// Reactor中的中介者实现
class ReactiveMediator {
private final Map<String, Sink<String>> commandSinks = new ConcurrentHashMap<>();
private final Flux<String> eventBus;
public ReactiveMediator() {
this.eventBus = Flux.<String>create(sink -> {
// 全局事件订阅
}).publish().autoConnect();
}
public void registerService(String serviceId) {
Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
commandSinks.put(serviceId, sink.asFlux());
}
public Flux<String> getServiceCommands(String serviceId) {
return commandSinks.getOrDefault(serviceId, Flux.empty());
}
public void sendCommand(String serviceId, String command) {
Sinks.Many<String> sink = (Sinks.Many<String>) commandSinks.get(serviceId);
if (sink != null) {
sink.tryEmitNext(command);
}
}
public void publishEvent(String event) {
eventBus.subscribe(event);
}
public Flux<String> getEventStream() {
return eventBus;
}
}
总结
中介者模式是管理复杂对象交互的强有力工具,特别适合对象间存在多对多关系的场景。其核心价值体现在:
- 交互解耦:消除对象间的直接引用
- 集中管理:统一维护交互规则
- 简化关系:将网状结构转为星型结构
- 灵活扩展:新增交互不影响现有对象
现代应用关键点:
- 合理划分职责:避免中介者承担过多责任
- 性能考量:分布式环境下的延迟问题
- 错误处理:健壮的中介错误恢复机制
- 与模式组合:结合观察者、命令等模式增强功能
- 分布式支持:适应微服务和云原生架构
中介者模式正在与响应式编程、服务网格等现代技术结合,演进出更强大的交互管理能力。掌握中介者模式的精髓,将帮助开发者构建出更加清晰、可维护的系统架构,特别是在复杂的分布式系统领域。