设计模式-中介者模式详解
中介者模式详解
目录
- 中介者模式简介
- 核心流程
- 重难点分析
- Spring中的源码分析
- 具体使用场景
- 面试高频点
- 使用总结
中介者模式简介
定义
中介者模式(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 {@Overridepublic void notify(Colleague sender, String message) {System.out.println("中介者转发消息: " + sender.getName() + " -> " + message);for (Colleague colleague : colleagues) {if (colleague != sender) {colleague.receive(message, sender);}}}@Overridepublic 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);}@Overridepublic void send(String message) {System.out.println(name + " 发送广播消息: " + message);mediator.notify(this, message);}@Overridepublic void send(String message, Colleague target) {System.out.println(name + " 发送私聊消息给 " + target.getName() + ": " + message);mediator.notify(this, message, target);}@Overridepublic 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);}@Overridepublic void send(String message) {System.out.println(name + " 发送广播消息: " + message);mediator.notify(this, message);}@Overridepublic void send(String message, Colleague target) {System.out.println(name + " 发送私聊消息给 " + target.getName() + ": " + message);mediator.notify(this, message, target);}@Overridepublic 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 {@Overridepublic 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);}}}}@Overridepublic 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);}@Overridepublic 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());}@Overridepublic void notify(String senderKey, String message) {messageQueue.offer(new MessageTask(senderKey, message, null));}@Overridepublic void notify(String senderKey, String message, String targetKey) {messageQueue.offer(new MessageTask(senderKey, message, targetKey));}private class MessageProcessor implements Runnable {@Overridepublic 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<>();@Overridepublic 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;@Overridepublic void initialize(ExtensibleMediator mediator) {this.mediator = mediator;}@Overridepublic void onColleagueRegistered(Colleague colleague) {System.out.println("同事注册: " + colleague.getName());}@Overridepublic void onMessageSent(Colleague sender, String message, Colleague target) {System.out.println("消息发送: " + sender.getName() + " -> " + (target != null ? target.getName() : "所有人") + " : " + message);}@Overridepublic void destroy() {System.out.println("日志插件销毁");}
}
重难点4:中介者的测试
问题描述
如何对中介者模式进行单元测试,确保交互逻辑的正确性。
解决方案
// 可测试的中介者
public class TestableMediator extends BaseMediator {private final List<MessageEvent> messageEvents = new ArrayList<>();@Overridepublic 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);}}}}@Overridepublic 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 {@Testpublic 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());}@Testpublic 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 DefaultResourceLoaderimplements ConfigurableApplicationContext {private ApplicationEventMulticaster applicationEventMulticaster;@Overridepublic void publishEvent(ApplicationEvent event) {publishEvent(event, null);}@Overridepublic 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 {@Overridepublic 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> {@Overridepublic 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;@Overridepublic void setMediator(OrderProcessingMediator mediator) {this.mediator = mediator;}@Overridepublic boolean canProcess(Order order) {return order.getStatus() == OrderStatus.PENDING;}@Overridepublic 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;@Overridepublic void setMediator(OrderProcessingMediator mediator) {this.mediator = mediator;}@Overridepublic boolean canProcess(Order order) {return order.getStatus() == OrderStatus.CONFIRMED;}@Overridepublic 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 {@Overridepublic 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 {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void createOrder(Order order) {// 创建订单逻辑eventPublisher.publishEvent(new OrderCreatedEvent(order));}
}// 2. 使用ApplicationListener
@Component
public class OrderEventListener implements ApplicationListener<OrderCreatedEvent> {@Overridepublic void onApplicationEvent(OrderCreatedEvent event) {// 处理订单创建事件System.out.println("订单创建: " + event.getOrder().getId());}
}
5. 设计原则相关
问题:中介者模式体现了哪些设计原则?
答案要点:
- 单一职责:中介者只负责协调对象交互
- 开闭原则:可以添加新的同事对象而不修改现有代码
- 依赖倒置:依赖抽象而不是具体实现
- 接口隔离:客户端只依赖需要的接口
6. 实际应用场景
问题:中介者模式适用于哪些场景?
答案要点:
- 聊天室系统:用户之间的消息传递
- 飞机控制系统:飞机与塔台之间的通信
- 订单处理系统:订单处理流程的协调
- 事件系统:事件发布和订阅
- GUI系统:界面组件之间的交互
使用总结
中介者模式的优势
- 解耦:减少对象之间的直接依赖关系
- 集中控制:将交互逻辑集中到中介者中
- 简化通信:简化对象之间的通信方式
- 易于维护:交互逻辑的修改只需要修改中介者
中介者模式的缺点
- 复杂度增加:中介者可能变得过于复杂
- 性能问题:中介者可能成为性能瓶颈
- 学习成本:需要理解中介者模式的概念
- 过度设计:简单场景可能不需要使用
使用建议
- 复杂交互:只用于复杂的对象交互场景
- 性能考虑:注意中介者的性能影响
- 扩展性:考虑中介者的扩展性设计
- 测试:做好中介者的单元测试
最佳实践
- 分层设计:使用分层中介者避免复杂度
- 策略模式:使用策略模式处理不同类型的消息
- 异步处理:使用异步处理提高性能
- 插件机制:使用插件机制提高扩展性
- 单元测试:为中介者编写完整的单元测试
与其他模式的对比
- 与观察者模式:中介者模式是协调交互,观察者模式是状态通知
- 与命令模式:中介者模式是协调对象,命令模式是封装请求
- 与策略模式:中介者模式是协调策略,策略模式是算法选择
中介者模式是一种有用的行为型设计模式,特别适用于需要协调复杂对象交互、集中控制交互逻辑、简化对象通信等场景。通过合理使用中介者模式,可以大大提高系统的可维护性和可扩展性。