中介者模式详解
目录
中介者模式简介
定义
中介者模式(Mediator Pattern)是一种行为型设计模式,它用一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
核心思想
- 解耦对象交互:通过中介者解耦对象之间的直接依赖关系
- 集中控制:将对象间的交互逻辑集中到中介者中
- 简化通信:简化对象之间的通信方式
- 易于维护:交互逻辑的修改只需要修改中介者
模式结构
- Mediator(抽象中介者):定义同事对象到中介者对象的接口
- ConcreteMediator(具体中介者):实现抽象中介者,协调各同事对象的交互关系
- Colleague(抽象同事类):定义各同事对象的公有接口
- ConcreteColleague(具体同事类):实现抽象同事类,通过中介者与其他同事对象通信
核心流程
中介者模式流程图
基本实现流程
1. 定义抽象中介者
// 抽象中介者
public abstract class Mediator {
protected List<Colleague> colleagues = new ArrayList<>();
public void register(Colleague colleague) {
colleagues.add(colleague);
colleague.setMediator(this);
}
public void unregister(Colleague colleague) {
colleagues.remove(colleague);
colleague.setMediator(null);
}
public abstract void notify(Colleague sender, String message);
public abstract void notify(Colleague sender, String message, Colleague target);
}
2. 定义抽象同事类
// 抽象同事类
public abstract class Colleague {
protected Mediator mediator;
protected String name;
public Colleague(String name) {
this.name = name;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public String getName() {
return name;
}
public abstract void send(String message);
public abstract void send(String message, Colleague target);
public abstract void receive(String message, Colleague sender);
}
3. 实现具体中介者
// 具体中介者
public class ConcreteMediator extends Mediator {
@Override
public void notify(Colleague sender, String message) {
System.out.println("中介者转发消息: " + sender.getName() + " -> " + message);
for (Colleague colleague : colleagues) {
if (colleague != sender) {
colleague.receive(message, sender);
}
}
}
@Override
public void notify(Colleague sender, String message, Colleague target) {
System.out.println("中介者转发消息: " + sender.getName() + " -> " + target.getName() + " : " + message);
if (colleagues.contains(target)) {
target.receive(message, sender);
}
}
}
4. 实现具体同事类
// 具体同事类A
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(String name) {
super(name);
}
@Override
public void send(String message) {
System.out.println(name + " 发送广播消息: " + message);
mediator.notify(this, message);
}
@Override
public void send(String message, Colleague target) {
System.out.println(name + " 发送私聊消息给 " + target.getName() + ": " + message);
mediator.notify(this, message, target);
}
@Override
public void receive(String message, Colleague sender) {
System.out.println(name + " 收到来自 " + sender.getName() + " 的消息: " + message);
}
}
// 具体同事类B
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(String name) {
super(name);
}
@Override
public void send(String message) {
System.out.println(name + " 发送广播消息: " + message);
mediator.notify(this, message);
}
@Override
public void send(String message, Colleague target) {
System.out.println(name + " 发送私聊消息给 " + target.getName() + ": " + message);
mediator.notify(this, message, target);
}
@Override
public void receive(String message, Colleague sender) {
System.out.println(name + " 收到来自 " + sender.getName() + " 的消息: " + message);
}
}
5. 客户端使用
public class Client {
public static void main(String[] args) {
// 创建中介者
Mediator mediator = new ConcreteMediator();
// 创建同事对象
Colleague colleagueA = new ConcreteColleagueA("同事A");
Colleague colleagueB = new ConcreteColleagueB("同事B");
// 注册同事对象到中介者
mediator.register(colleagueA);
mediator.register(colleagueB);
// 发送消息
colleagueA.send("大家好,我是同事A");
colleagueB.send("你好,我是同事B");
colleagueA.send("你好", colleagueB);
}
}
重难点分析
重难点1:中介者的复杂度管理
问题描述
随着同事对象数量的增加,中介者可能变得过于复杂,难以维护。
解决方案
// 分层中介者模式
public abstract class BaseMediator {
protected Map<String, Colleague> colleagues = new HashMap<>();
public void register(String key, Colleague colleague) {
colleagues.put(key, colleague);
colleague.setMediator(this);
}
public Colleague getColleague(String key) {
return colleagues.get(key);
}
public abstract void notify(String senderKey, String message);
public abstract void notify(String senderKey, String message, String targetKey);
}
// 具体中介者实现
public class ChatMediator extends BaseMediator {
@Override
public void notify(String senderKey, String message) {
Colleague sender = getColleague(senderKey);
if (sender != null) {
System.out.println("广播消息: " + sender.getName() + " -> " + message);
for (Colleague colleague : colleagues.values()) {
if (colleague != sender) {
colleague.receive(message, sender);
}
}
}
}
@Override
public void notify(String senderKey, String message, String targetKey) {
Colleague sender = getColleague(senderKey);
Colleague target = getColleague(targetKey);
if (sender != null && target != null) {
System.out.println("私聊消息: " + sender.getName() + " -> " + target.getName() + " : " + message);
target.receive(message, sender);
}
}
}
// 使用策略模式的中介者
public class StrategyMediator extends BaseMediator {
private Map<String, MessageStrategy> strategies = new HashMap<>();
public void addStrategy(String messageType, MessageStrategy strategy) {
strategies.put(messageType, strategy);
}
@Override
public void notify(String senderKey, String message) {
Colleague sender = getColleague(senderKey);
if (sender != null) {
String messageType = extractMessageType(message);
MessageStrategy strategy = strategies.get(messageType);
if (strategy != null) {
strategy.handleMessage(sender, message, colleagues);
} else {
// 默认处理
defaultHandleMessage(sender, message);
}
}
}
private String extractMessageType(String message) {
// 根据消息内容提取类型
if (message.startsWith("@")) {
return "PRIVATE";
} else if (message.startsWith("#")) {
return "GROUP";
}
return "BROADCAST";
}
private void defaultHandleMessage(Colleague sender, String message) {
System.out.println("默认处理: " + sender.getName() + " -> " + message);
}
}
重难点2:中介者的性能优化
问题描述
中介者可能成为性能瓶颈,特别是在高并发场景下。
解决方案
// 异步中介者
public class AsyncMediator extends BaseMediator {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
private final BlockingQueue<MessageTask> messageQueue = new LinkedBlockingQueue<>();
public AsyncMediator() {
// 启动消息处理线程
executor.submit(new MessageProcessor());
}
@Override
public void notify(String senderKey, String message) {
messageQueue.offer(new MessageTask(senderKey, message, null));
}
@Override
public void notify(String senderKey, String message, String targetKey) {
messageQueue.offer(new MessageTask(senderKey, message, targetKey));
}
private class MessageProcessor implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
MessageTask task = messageQueue.take();
processMessage(task);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}
private void processMessage(MessageTask task) {
Colleague sender = getColleague(task.getSenderKey());
if (sender != null) {
if (task.getTargetKey() != null) {
Colleague target = getColleague(task.getTargetKey());
if (target != null) {
target.receive(task.getMessage(), sender);
}
} else {
for (Colleague colleague : colleagues.values()) {
if (colleague != sender) {
colleague.receive(task.getMessage(), sender);
}
}
}
}
}
public void shutdown() {
executor.shutdown();
}
}
// 消息任务类
public class MessageTask {
private final String senderKey;
private final String message;
private final String targetKey;
public MessageTask(String senderKey, String message, String targetKey) {
this.senderKey = senderKey;
this.message = message;
this.targetKey = targetKey;
}
// getter方法
public String getSenderKey() { return senderKey; }
public String getMessage() { return message; }
public String getTargetKey() { return targetKey; }
}
重难点3:中介者的扩展性
问题描述
如何让中介者模式具有良好的扩展性,支持新的同事对象类型。
解决方案
// 可扩展的中介者
public class ExtensibleMediator extends BaseMediator {
private final Map<Class<?>, List<Colleague>> colleaguesByType = new HashMap<>();
private final Map<String, MediatorPlugin> plugins = new HashMap<>();
@Override
public void register(String key, Colleague colleague) {
super.register(key, colleague);
// 按类型分组
Class<?> colleagueType = colleague.getClass();
colleaguesByType.computeIfAbsent(colleagueType, k -> new ArrayList<>()).add(colleague);
// 通知插件
for (MediatorPlugin plugin : plugins.values()) {
plugin.onColleagueRegistered(colleague);
}
}
public void addPlugin(String name, MediatorPlugin plugin) {
plugins.put(name, plugin);
plugin.initialize(this);
}
public void removePlugin(String name) {
MediatorPlugin plugin = plugins.remove(name);
if (plugin != null) {
plugin.destroy();
}
}
public <T extends Colleague> List<T> getColleaguesByType(Class<T> type) {
List<Colleague> colleagues = colleaguesByType.get(type);
if (colleagues != null) {
return colleagues.stream()
.map(type::cast)
.collect(Collectors.toList());
}
return Collections.emptyList();
}
}
// 中介者插件接口
public interface MediatorPlugin {
void initialize(ExtensibleMediator mediator);
void onColleagueRegistered(Colleague colleague);
void onMessageSent(Colleague sender, String message, Colleague target);
void destroy();
}
// 日志插件
public class LoggingPlugin implements MediatorPlugin {
private ExtensibleMediator mediator;
@Override
public void initialize(ExtensibleMediator mediator) {
this.mediator = mediator;
}
@Override
public void onColleagueRegistered(Colleague colleague) {
System.out.println("同事注册: " + colleague.getName());
}
@Override
public void onMessageSent(Colleague sender, String message, Colleague target) {
System.out.println("消息发送: " + sender.getName() + " -> " +
(target != null ? target.getName() : "所有人") + " : " + message);
}
@Override
public void destroy() {
System.out.println("日志插件销毁");
}
}
重难点4:中介者的测试
问题描述
如何对中介者模式进行单元测试,确保交互逻辑的正确性。
解决方案
// 可测试的中介者
public class TestableMediator extends BaseMediator {
private final List<MessageEvent> messageEvents = new ArrayList<>();
@Override
public void notify(String senderKey, String message) {
Colleague sender = getColleague(senderKey);
if (sender != null) {
messageEvents.add(new MessageEvent(sender, message, null, MessageType.BROADCAST));
for (Colleague colleague : colleagues.values()) {
if (colleague != sender) {
colleague.receive(message, sender);
}
}
}
}
@Override
public void notify(String senderKey, String message, String targetKey) {
Colleague sender = getColleague(senderKey);
Colleague target = getColleague(targetKey);
if (sender != null && target != null) {
messageEvents.add(new MessageEvent(sender, message, target, MessageType.PRIVATE));
target.receive(message, sender);
}
}
public List<MessageEvent> getMessageEvents() {
return new ArrayList<>(messageEvents);
}
public void clearMessageEvents() {
messageEvents.clear();
}
}
// 消息事件类
public class MessageEvent {
private final Colleague sender;
private final String message;
private final Colleague target;
private final MessageType type;
private final long timestamp;
public MessageEvent(Colleague sender, String message, Colleague target, MessageType type) {
this.sender = sender;
this.message = message;
this.target = target;
this.type = type;
this.timestamp = System.currentTimeMillis();
}
// getter方法
public Colleague getSender() { return sender; }
public String getMessage() { return message; }
public Colleague getTarget() { return target; }
public MessageType getType() { return type; }
public long getTimestamp() { return timestamp; }
}
// 消息类型枚举
public enum MessageType {
BROADCAST, PRIVATE, GROUP
}
// 单元测试
public class MediatorTest {
@Test
public void testBroadcastMessage() {
TestableMediator mediator = new TestableMediator();
Colleague colleagueA = new ConcreteColleagueA("A");
Colleague colleagueB = new ConcreteColleagueB("B");
mediator.register("A", colleagueA);
mediator.register("B", colleagueB);
colleagueA.send("Hello");
List<MessageEvent> events = mediator.getMessageEvents();
assertEquals(1, events.size());
assertEquals("A", events.get(0).getSender().getName());
assertEquals("Hello", events.get(0).getMessage());
assertEquals(MessageType.BROADCAST, events.get(0).getType());
}
@Test
public void testPrivateMessage() {
TestableMediator mediator = new TestableMediator();
Colleague colleagueA = new ConcreteColleagueA("A");
Colleague colleagueB = new ConcreteColleagueB("B");
mediator.register("A", colleagueA);
mediator.register("B", colleagueB);
colleagueA.send("Hello", colleagueB);
List<MessageEvent> events = mediator.getMessageEvents();
assertEquals(1, events.size());
assertEquals("A", events.get(0).getSender().getName());
assertEquals("B", events.get(0).getTarget().getName());
assertEquals("Hello", events.get(0).getMessage());
assertEquals(MessageType.PRIVATE, events.get(0).getType());
}
}
Spring中的源码分析
Spring的ApplicationContext作为中介者
// ApplicationContext接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
void publishEvent(ApplicationEvent event);
void publishEvent(Object event);
}
Spring的ApplicationEventPublisher
// ApplicationEventPublisher接口
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
void publishEvent(Object event);
}
// AbstractApplicationContext中的实现
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
private ApplicationEventMulticaster applicationEventMulticaster;
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
@Override
public void publishEvent(Object event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
} else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
}
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
} else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
} else {
this.parent.publishEvent(event);
}
}
}
}
Spring的ApplicationEventMulticaster
// ApplicationEventMulticaster接口
public interface ApplicationEventMulticaster {
void addApplicationListener(ApplicationListener<?> listener);
void addApplicationListenerBean(String listenerBeanName);
void removeApplicationListener(ApplicationListener<?> listener);
void removeApplicationListenerBean(String listenerBeanName);
void removeAllListeners();
void multicastEvent(ApplicationEvent event);
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
// SimpleApplicationEventMulticaster实现
public class SimpleApplicationEventMulticaster implements ApplicationEventMulticaster {
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
} else {
invokeListener(listener, event);
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private void invokeListener(ApplicationListener listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
listener.onApplicationEvent(event);
} catch (Throwable err) {
errorHandler.handleError(err);
}
} else {
listener.onApplicationEvent(event);
}
}
}
Spring的ApplicationListener
// ApplicationListener接口
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
// 使用示例
@Component
public class UserEventListener implements ApplicationListener<UserRegisteredEvent> {
@Override
public void onApplicationEvent(UserRegisteredEvent event) {
System.out.println("用户注册事件: " + event.getUsername());
// 处理用户注册逻辑
}
}
// 事件类
public class UserRegisteredEvent extends ApplicationEvent {
private final String username;
private final String email;
public UserRegisteredEvent(Object source, String username, String email) {
super(source);
this.username = username;
this.email = email;
}
public String getUsername() { return username; }
public String getEmail() { return email; }
}
具体使用场景
1. 聊天室系统
// 聊天室中介者
public class ChatRoomMediator {
private final Map<String, User> users = new HashMap<>();
private final List<ChatMessage> messages = new ArrayList<>();
public void addUser(User user) {
users.put(user.getId(), user);
user.setMediator(this);
broadcastSystemMessage(user.getName() + " 加入了聊天室");
}
public void removeUser(String userId) {
User user = users.remove(userId);
if (user != null) {
user.setMediator(null);
broadcastSystemMessage(user.getName() + " 离开了聊天室");
}
}
public void sendMessage(String senderId, String message) {
User sender = users.get(senderId);
if (sender != null) {
ChatMessage chatMessage = new ChatMessage(sender, message, System.currentTimeMillis());
messages.add(chatMessage);
broadcastMessage(chatMessage);
}
}
public void sendPrivateMessage(String senderId, String receiverId, String message) {
User sender = users.get(senderId);
User receiver = users.get(receiverId);
if (sender != null && receiver != null) {
ChatMessage chatMessage = new ChatMessage(sender, message, System.currentTimeMillis());
receiver.receiveMessage(chatMessage);
}
}
private void broadcastMessage(ChatMessage message) {
for (User user : users.values()) {
if (user != message.getSender()) {
user.receiveMessage(message);
}
}
}
private void broadcastSystemMessage(String message) {
ChatMessage systemMessage = new ChatMessage(null, "[系统] " + message, System.currentTimeMillis());
for (User user : users.values()) {
user.receiveMessage(systemMessage);
}
}
}
// 用户类
public class User {
private final String id;
private final String name;
private ChatRoomMediator mediator;
public User(String id, String name) {
this.id = id;
this.name = name;
}
public void setMediator(ChatRoomMediator mediator) {
this.mediator = mediator;
}
public void sendMessage(String message) {
if (mediator != null) {
mediator.sendMessage(id, message);
}
}
public void sendPrivateMessage(String receiverId, String message) {
if (mediator != null) {
mediator.sendPrivateMessage(id, receiverId, message);
}
}
public void receiveMessage(ChatMessage message) {
System.out.println(name + " 收到消息: " + message.getContent());
}
// getter方法
public String getId() { return id; }
public String getName() { return name; }
}
// 聊天消息类
public class ChatMessage {
private final User sender;
private final String content;
private final long timestamp;
public ChatMessage(User sender, String content, long timestamp) {
this.sender = sender;
this.content = content;
this.timestamp = timestamp;
}
// getter方法
public User getSender() { return sender; }
public String getContent() { return content; }
public long getTimestamp() { return timestamp; }
}
2. 飞机控制系统
// 飞机控制中介者
public class AirTrafficControlMediator {
private final Map<String, Aircraft> aircrafts = new HashMap<>();
private final List<Runway> runways = new ArrayList<>();
private final List<Gate> gates = new ArrayList<>();
public void registerAircraft(Aircraft aircraft) {
aircrafts.put(aircraft.getId(), aircraft);
aircraft.setMediator(this);
}
public void requestLanding(String aircraftId) {
Aircraft aircraft = aircrafts.get(aircraftId);
if (aircraft != null) {
Runway availableRunway = findAvailableRunway();
if (availableRunway != null) {
availableRunway.setOccupied(true);
aircraft.land(availableRunway);
System.out.println("飞机 " + aircraftId + " 被分配到跑道 " + availableRunway.getId());
} else {
aircraft.waitForRunway();
System.out.println("飞机 " + aircraftId + " 需要等待可用跑道");
}
}
}
public void requestTakeoff(String aircraftId) {
Aircraft aircraft = aircrafts.get(aircraftId);
if (aircraft != null) {
Runway availableRunway = findAvailableRunway();
if (availableRunway != null) {
availableRunway.setOccupied(true);
aircraft.takeoff(availableRunway);
System.out.println("飞机 " + aircraftId + " 从跑道 " + availableRunway.getId() + " 起飞");
} else {
aircraft.waitForRunway();
System.out.println("飞机 " + aircraftId + " 需要等待可用跑道");
}
}
}
public void requestGate(String aircraftId) {
Aircraft aircraft = aircrafts.get(aircraftId);
if (aircraft != null) {
Gate availableGate = findAvailableGate();
if (availableGate != null) {
availableGate.setOccupied(true);
aircraft.park(availableGate);
System.out.println("飞机 " + aircraftId + " 被分配到登机口 " + availableGate.getId());
} else {
aircraft.waitForGate();
System.out.println("飞机 " + aircraftId + " 需要等待可用登机口");
}
}
}
private Runway findAvailableRunway() {
return runways.stream()
.filter(runway -> !runway.isOccupied())
.findFirst()
.orElse(null);
}
private Gate findAvailableGate() {
return gates.stream()
.filter(gate -> !gate.isOccupied())
.findFirst()
.orElse(null);
}
}
// 飞机类
public class Aircraft {
private final String id;
private final String type;
private AirTrafficControlMediator mediator;
public Aircraft(String id, String type) {
this.id = id;
this.type = type;
}
public void setMediator(AirTrafficControlMediator mediator) {
this.mediator = mediator;
}
public void requestLanding() {
if (mediator != null) {
mediator.requestLanding(id);
}
}
public void requestTakeoff() {
if (mediator != null) {
mediator.requestTakeoff(id);
}
}
public void requestGate() {
if (mediator != null) {
mediator.requestGate(id);
}
}
public void land(Runway runway) {
System.out.println("飞机 " + id + " 降落在跑道 " + runway.getId());
}
public void takeoff(Runway runway) {
System.out.println("飞机 " + id + " 从跑道 " + runway.getId() + " 起飞");
}
public void park(Gate gate) {
System.out.println("飞机 " + id + " 停靠在登机口 " + gate.getId());
}
public void waitForRunway() {
System.out.println("飞机 " + id + " 等待可用跑道");
}
public void waitForGate() {
System.out.println("飞机 " + id + " 等待可用登机口");
}
// getter方法
public String getId() { return id; }
public String getType() { return type; }
}
3. 订单处理系统
// 订单处理中介者
public class OrderProcessingMediator {
private final Map<String, Order> orders = new HashMap<>();
private final List<OrderProcessor> processors = new ArrayList<>();
private final List<OrderObserver> observers = new ArrayList<>();
public void registerProcessor(OrderProcessor processor) {
processors.add(processor);
processor.setMediator(this);
}
public void registerObserver(OrderObserver observer) {
observers.add(observer);
}
public void processOrder(Order order) {
orders.put(order.getId(), order);
notifyObservers("订单创建", order);
for (OrderProcessor processor : processors) {
if (processor.canProcess(order)) {
processor.process(order);
break;
}
}
}
public void updateOrderStatus(String orderId, OrderStatus status) {
Order order = orders.get(orderId);
if (order != null) {
order.setStatus(status);
notifyObservers("订单状态更新", order);
}
}
private void notifyObservers(String event, Order order) {
for (OrderObserver observer : observers) {
observer.onOrderEvent(event, order);
}
}
}
// 订单类
public class Order {
private final String id;
private final String customerId;
private final List<OrderItem> items;
private OrderStatus status;
private final long createTime;
public Order(String id, String customerId, List<OrderItem> items) {
this.id = id;
this.customerId = customerId;
this.items = items;
this.status = OrderStatus.PENDING;
this.createTime = System.currentTimeMillis();
}
// getter和setter方法
public String getId() { return id; }
public String getCustomerId() { return customerId; }
public List<OrderItem> getItems() { return items; }
public OrderStatus getStatus() { return status; }
public void setStatus(OrderStatus status) { this.status = status; }
public long getCreateTime() { return createTime; }
}
// 订单处理器接口
public interface OrderProcessor {
void setMediator(OrderProcessingMediator mediator);
boolean canProcess(Order order);
void process(Order order);
}
// 库存验证处理器
public class InventoryValidator implements OrderProcessor {
private OrderProcessingMediator mediator;
@Override
public void setMediator(OrderProcessingMediator mediator) {
this.mediator = mediator;
}
@Override
public boolean canProcess(Order order) {
return order.getStatus() == OrderStatus.PENDING;
}
@Override
public void process(Order order) {
System.out.println("验证订单库存: " + order.getId());
// 验证库存逻辑
if (validateInventory(order)) {
mediator.updateOrderStatus(order.getId(), OrderStatus.CONFIRMED);
} else {
mediator.updateOrderStatus(order.getId(), OrderStatus.CANCELLED);
}
}
private boolean validateInventory(Order order) {
// 模拟库存验证
return true;
}
}
// 支付处理器
public class PaymentProcessor implements OrderProcessor {
private OrderProcessingMediator mediator;
@Override
public void setMediator(OrderProcessingMediator mediator) {
this.mediator = mediator;
}
@Override
public boolean canProcess(Order order) {
return order.getStatus() == OrderStatus.CONFIRMED;
}
@Override
public void process(Order order) {
System.out.println("处理订单支付: " + order.getId());
// 支付处理逻辑
if (processPayment(order)) {
mediator.updateOrderStatus(order.getId(), OrderStatus.PAID);
} else {
mediator.updateOrderStatus(order.getId(), OrderStatus.PAYMENT_FAILED);
}
}
private boolean processPayment(Order order) {
// 模拟支付处理
return true;
}
}
面试高频点
面试知识点思维导图
1. 中介者模式的基本概念
问题:什么是中介者模式?
答案要点:
- 用一个中介对象来封装一系列对象之间的交互
- 使各对象不需要显式地相互引用,从而使其耦合松散
- 属于行为型设计模式
- 可以独立地改变它们之间的交互
问题:中介者模式有哪些角色?
答案要点:
- Mediator(抽象中介者):定义同事对象到中介者对象的接口
- ConcreteMediator(具体中介者):实现抽象中介者,协调各同事对象的交互关系
- Colleague(抽象同事类):定义各同事对象的公有接口
- ConcreteColleague(具体同事类):实现抽象同事类,通过中介者与其他同事对象通信
2. 实现方式相关
问题:如何实现中介者模式?
答案要点:
// 1. 定义抽象中介者
public abstract class Mediator {
protected List<Colleague> colleagues = new ArrayList<>();
public void register(Colleague colleague) {
colleagues.add(colleague);
colleague.setMediator(this);
}
public abstract void notify(Colleague sender, String message);
}
// 2. 定义抽象同事类
public abstract class Colleague {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message, Colleague sender);
}
// 3. 实现具体中介者
public class ConcreteMediator extends Mediator {
@Override
public void notify(Colleague sender, String message) {
for (Colleague colleague : colleagues) {
if (colleague != sender) {
colleague.receive(message, sender);
}
}
}
}
3. 重难点问题
问题:中介者模式与观察者模式的区别?
答案要点:
- 目的:中介者模式是协调对象交互,观察者模式是通知状态变化
- 关系:中介者模式是一对多,观察者模式是一对多
- 耦合度:中介者模式耦合度更高,观察者模式耦合度更低
- 使用场景:中介者模式用于复杂交互,观察者模式用于状态通知
问题:如何解决中介者的复杂度问题?
答案要点:
// 1. 分层中介者
public class LayeredMediator {
private final Map<String, Mediator> mediators = new HashMap<>();
public void addMediator(String layer, Mediator mediator) {
mediators.put(layer, mediator);
}
public void notify(String layer, Colleague sender, String message) {
Mediator mediator = mediators.get(layer);
if (mediator != null) {
mediator.notify(sender, message);
}
}
}
// 2. 使用策略模式
public class StrategyMediator {
private final Map<String, MessageStrategy> strategies = new HashMap<>();
public void addStrategy(String messageType, MessageStrategy strategy) {
strategies.put(messageType, strategy);
}
public void notify(Colleague sender, String message) {
String messageType = extractMessageType(message);
MessageStrategy strategy = strategies.get(messageType);
if (strategy != null) {
strategy.handleMessage(sender, message);
}
}
}
4. Spring中的应用
问题:Spring中如何使用中介者模式?
答案要点:
// 1. 使用ApplicationEventPublisher
@Component
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createOrder(Order order) {
// 创建订单逻辑
eventPublisher.publishEvent(new OrderCreatedEvent(order));
}
}
// 2. 使用ApplicationListener
@Component
public class OrderEventListener implements ApplicationListener<OrderCreatedEvent> {
@Override
public void onApplicationEvent(OrderCreatedEvent event) {
// 处理订单创建事件
System.out.println("订单创建: " + event.getOrder().getId());
}
}
5. 设计原则相关
问题:中介者模式体现了哪些设计原则?
答案要点:
- 单一职责:中介者只负责协调对象交互
- 开闭原则:可以添加新的同事对象而不修改现有代码
- 依赖倒置:依赖抽象而不是具体实现
- 接口隔离:客户端只依赖需要的接口
6. 实际应用场景
问题:中介者模式适用于哪些场景?
答案要点:
- 聊天室系统:用户之间的消息传递
- 飞机控制系统:飞机与塔台之间的通信
- 订单处理系统:订单处理流程的协调
- 事件系统:事件发布和订阅
- GUI系统:界面组件之间的交互
使用总结
中介者模式的优势
- 解耦:减少对象之间的直接依赖关系
- 集中控制:将交互逻辑集中到中介者中
- 简化通信:简化对象之间的通信方式
- 易于维护:交互逻辑的修改只需要修改中介者
中介者模式的缺点
- 复杂度增加:中介者可能变得过于复杂
- 性能问题:中介者可能成为性能瓶颈
- 学习成本:需要理解中介者模式的概念
- 过度设计:简单场景可能不需要使用
使用建议
- 复杂交互:只用于复杂的对象交互场景
- 性能考虑:注意中介者的性能影响
- 扩展性:考虑中介者的扩展性设计
- 测试:做好中介者的单元测试
最佳实践
- 分层设计:使用分层中介者避免复杂度
- 策略模式:使用策略模式处理不同类型的消息
- 异步处理:使用异步处理提高性能
- 插件机制:使用插件机制提高扩展性
- 单元测试:为中介者编写完整的单元测试
与其他模式的对比
- 与观察者模式:中介者模式是协调交互,观察者模式是状态通知
- 与命令模式:中介者模式是协调对象,命令模式是封装请求
- 与策略模式:中介者模式是协调策略,策略模式是算法选择
中介者模式是一种有用的行为型设计模式,特别适用于需要协调复杂对象交互、集中控制交互逻辑、简化对象通信等场景。通过合理使用中介者模式,可以大大提高系统的可维护性和可扩展性。
2752

被折叠的 条评论
为什么被折叠?



