前言
当系统中对象交互复杂如"蜘蛛网"时,中介者模式就是你的架构救星!本文将揭秘如何用中介者模式优雅解耦对象通信,让系统维护成本直降80%!
一、中介者模式:对象交互的交通指挥官
1.1 现实中的中介者模式
想象一个电商订单系统:
用户下单 → 通知库存系统
支付成功 → 通知物流系统
发货完成 → 通知用户系统
传统实现痛点:
// 支付服务中耦合多个系统调用
public class PaymentService {
public void processPayment(Order order) {
// 支付处理逻辑
paymentGateway.charge(order);
// 直接调用多个系统(高耦合)
inventoryService.reduceStock(order); // 通知库存
shippingService.scheduleDelivery(order); // 通知物流
notificationService.sendEmail(order.getUser()); // 通知用户
pointsService.addPoints(order.getUser(), order.getAmount()); // 增加积分
}
}
1.2 中介者模式核心思想
四大核心组件:
Mediator(中介者):定义对象间通信的接口
ConcreteMediator(具体中介者):协调各对象,实现协作逻辑
Colleague(同事类):定义与其他对象通信的接口
ConcreteColleague(具体同事类):通过中介者与其他对象通信
二、Spring Boot中的中介者模式实战
订单处理场景
假设订单流程需要协调:
支付服务
库存服务
物流服务
通知服务
积分服务
步骤1:定义中介者接口
public interface OrderMediator {
void notify(Object sender, String event, Order order);
}
步骤2:实现具体中介者
@Component
public class OrderProcessingMediator implements OrderMediator {
@Autowired
private PaymentService paymentService;
@Autowired
private InventoryService inventoryService;
@Autowired
private ShippingService shippingService;
@Autowired
private NotificationService notificationService;
@Autowired
private PointsService pointsService;
@Override
public void notify(Object sender, String event, Order order) {
if ("PAYMENT_SUCCESS".equals(event)) {
inventoryService.reduceStock(order);
shippingService.scheduleDelivery(order);
} else if ("SHIPPING_COMPLETE".equals(event)) {
notificationService.sendShippingComplete(order.getUser());
pointsService.addPoints(order.getUser(), order.getAmount());
} else if ("PAYMENT_FAILED".equals(event)) {
notificationService.sendPaymentFailed(order.getUser());
inventoryService.rollbackStock(order);
}
}
}
步骤3:定义同事类基类
public abstract class OrderComponent {
protected OrderMediator mediator;
public OrderComponent(OrderMediator mediator) {
this.mediator = mediator;
}
public void setMediator(OrderMediator mediator) {
this.mediator = mediator;
}
}
步骤4:实现具体同事类
@Service
public class PaymentService extends OrderComponent {
public PaymentService(OrderMediator mediator) {
super(mediator);
}
public void processPayment(Order order) {
try {
// 支付处理逻辑
paymentGateway.charge(order);
// 通过中介者通知其他服务
mediator.notify(this, "PAYMENT_SUCCESS", order);
} catch (PaymentException e) {
mediator.notify(this, "PAYMENT_FAILED", order);
}
}
}
@Service
public class ShippingService extends OrderComponent {
public ShippingService(OrderMediator mediator) {
super(mediator);
}
public void completeShipping(Order order) {
// 发货完成逻辑
markAsShipped(order);
// 通过中介者通知其他服务
mediator.notify(this, "SHIPPING_COMPLETE", order);
}
}
步骤5:在控制器中使用
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private PaymentService paymentService;
@Autowired
private ShippingService shippingService;
@PostMapping("/{orderId}/pay")
public ResponseEntity<?> payOrder(@PathVariable String orderId) {
Order order = orderService.getOrder(orderId);
paymentService.processPayment(order);
return ResponseEntity.ok("支付处理中");
}
@PostMapping("/{orderId}/ship")
public ResponseEntity<?> shipOrder(@PathVariable String orderId) {
Order order = orderService.getOrder(orderId);
shippingService.completeShipping(order);
return ResponseEntity.ok("发货完成");
}
}
三、中介者模式在Spring Boot中的高级应用
3.1 微服务通信协调
场景:在微服务架构中协调多个服务
@RestController
public class ServiceMediatorController {
@Autowired
private ServiceMediator mediator;
@PostMapping("/event")
public void handleEvent(@RequestBody ServiceEvent event) {
mediator.notify(event.getSource(), event.getType(), event.getData());
}
}
@Component
public class ServiceMediator {
private final Map<String, ServiceHandler> handlers = new ConcurrentHashMap<>();
public void registerHandler(String eventType, ServiceHandler handler) {
handlers.put(eventType, handler);
}
public void notify(String source, String eventType, Object data) {
ServiceHandler handler = handlers.get(eventType);
if (handler != null) {
handler.handle(source, data);
}
}
}
// 注册处理器
@Configuration
public class MediatorConfig {
@Autowired
private ServiceMediator mediator;
@PostConstruct
public void init() {
mediator.registerHandler("USER_CREATED", (source, data) -> {
// 用户创建事件处理
notificationService.sendWelcomeEmail((User) data);
pointsService.grantSignupPoints((User) data);
});
mediator.registerHandler("ORDER_CANCELLED", (source, data) -> {
// 订单取消事件处理
inventoryService.restockItems((Order) data);
paymentService.refundPayment((Order) data);
});
}
}
3.2 分布式事务协调
场景:跨服务的事务协调
@Component
public class TransactionMediator {
@Autowired
private OrderService orderService;
@Autowired
private InventoryService inventoryService;
@Autowired
private PaymentService paymentService;
@Transactional
public void processOrder(Order order) {
// 开始事务
TransactionStatus status = transactionManager.getTransaction(null);
try {
// 协调多个服务
orderService.createOrder(order);
inventoryService.reduceStock(order);
paymentService.processPayment(order);
// 提交事务
transactionManager.commit(status);
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(status);
mediator.notify(this, "TRANSACTION_FAILED", order);
throw e;
}
}
}
3.3 UI组件交互
场景:前端复杂表单组件交互
// 注册表单中介者
@Component
public class RegistrationFormMediator {
private final Map<String, FormComponent> components = new HashMap<>();
public void registerComponent(String id, FormComponent component) {
components.put(id, component);
}
public void notify(String sourceId, String event) {
if ("usernameField.change".equals(event)) {
// 用户名变更时检查可用性
String username = components.get("usernameField").getValue();
boolean available = userService.checkUsernameAvailable(username);
components.get("usernameHint").setVisible(!available);
} else if ("passwordField.change".equals(event)) {
// 密码变更时检查强度
String password = components.get("passwordField").getValue();
int strength = passwordService.checkStrength(password);
components.get("strengthIndicator").update(strength);
}
}
}
// 在Thymeleaf中使用
<div id="registrationForm">
<input type="text" id="usernameField" onchange="mediator.notify('usernameField', 'change')">
<span id="usernameHint" style="display:none">用户名已存在</span>
<input type="password" id="passwordField" onchange="mediator.notify('passwordField', 'change')">
<div id="strengthIndicator"></div>
</div>
四、中介者模式的优势与适用场景
4.1 五大核心优势
解耦神器:对象间不直接引用,通过中介者通信
简化交互:多对多交互变为一对多
集中控制:交互逻辑集中在中介者
可扩展性:新增同事类不影响现有系统
职责清晰:各对象职责单一,中介者负责协调
4.2 六大适用场景
复杂交互系统:对象间交互复杂、混乱
UI组件协调:表单验证、组件联动
分布式系统:微服务间协调通信
工作流引擎:多步骤流程协调
聊天系统:协调多个用户间消息
交易系统:协调订单、支付、库存等
五、中介者模式与其他模式对比
5.1 中介者模式 vs 观察者模式
维度 |
中介者模式 |
观察者模式 |
---|---|---|
交互方向 | 双向通信 |
单向通知 |
耦合度 | 同事类与中介者耦合 |
观察者与主题耦合 |
控制中心 | 中介者控制所有交互 |
无中心控制 |
适用场景 | 复杂交互协调 |
状态变化通知 |
典型实现 | 聊天室、交易系统 |
事件通知、日志系统 |
5.2 中介者模式 vs 外观模式
维度 |
中介者模式 |
外观模式 |
---|---|---|
核心目的 | 协调对象间交互 |
简化复杂系统接口 |
交互对象 | 同级对象间协调 |
为客户端提供统一接口 |
关注点 | 对象间通信 |
子系统封装 |
关系类型 | 多对多关系 |
一对多关系 |
典型场景 | 组件协调、流程控制 |
API网关、服务封装 |
六、Spring Boot中的最佳实践
6.1 中介者工厂模式
@Component
public class MediatorFactory {
private final Map<Class<?>, Mediator> mediators = new ConcurrentHashMap<>();
@Autowired
public MediatorFactory(List<Mediator> mediatorList) {
mediatorList.forEach(mediator ->
mediators.put(mediator.getClass(), mediator)
);
}
public <T extends Mediator> T getMediator(Class<T> mediatorType) {
return mediatorType.cast(mediators.get(mediatorType));
}
}
// 在服务中使用
@Service
public class OrderService {
private final OrderMediator mediator;
@Autowired
public OrderService(MediatorFactory factory) {
this.mediator = factory.getMediator(OrderMediator.class);
}
}
6.2 中介者与Spring事件结合
// 自定义事件
public class OrderEvent extends ApplicationEvent {
private final String eventType;
private final Order order;
public OrderEvent(Object source, String eventType, Order order) {
super(source);
this.eventType = eventType;
this.order = order;
}
// getters...
}
// 中介者监听事件
@Component
public class OrderEventMediator {
private final Map<String, Consumer<Order>> handlers = new ConcurrentHashMap<>();
public void registerHandler(String eventType, Consumer<Order> handler) {
handlers.put(eventType, handler);
}
@EventListener
public void handleOrderEvent(OrderEvent event) {
Consumer<Order> handler = handlers.get(event.getEventType());
if (handler != null) {
handler.accept(event.getOrder());
}
}
}
// 注册处理器
@Configuration
public class OrderMediatorConfig {
@Autowired
private OrderEventMediator mediator;
@Autowired
private InventoryService inventoryService;
@PostConstruct
public void init() {
mediator.registerHandler("PAYMENT_SUCCESS", order -> {
inventoryService.reduceStock(order);
// 其他处理...
});
}
}
6.3 中介者模式中的异常处理
@Component
public class ErrorHandlingMediator implements OrderMediator {
private final OrderMediator delegate;
private final ErrorHandler errorHandler;
public ErrorHandlingMediator(OrderMediator delegate, ErrorHandler errorHandler) {
this.delegate = delegate;
this.errorHandler = errorHandler;
}
@Override
public void notify(Object sender, String event, Order order) {
try {
delegate.notify(sender, event, order);
} catch (Exception e) {
errorHandler.handle(e, sender, event, order);
}
}
}
// 统一错误处理
@Component
public class DefaultErrorHandler implements ErrorHandler {
@Override
public void handle(Exception ex, Object sender, String event, Order order) {
// 记录错误日志
log.error("中介者处理事件失败: sender={}, event={}, order={}",
sender.getClass().getSimpleName(), event, order.getId(), ex);
// 发送警报
alertService.sendAlert("中介者错误", ex.getMessage());
// 回滚操作
if ("PAYMENT_SUCCESS".equals(event)) {
inventoryService.rollbackStock(order);
}
}
}
七、中介者模式的局限与解决方案
7.1 常见问题及对策
问题 |
解决方案 |
---|---|
中介者过于复杂 | 拆分子中介者,使用组合模式 |
性能瓶颈 | 异步处理、批量操作 |
单点故障 | 中介者集群化部署 |
扩展困难 | 使用插件机制动态注册处理器 |
调试困难 | 添加详细日志和跟踪ID |
7.2 何时避免使用中介者模式
对象间交互简单直接
系统规模小,对象数量少
交互逻辑稳定不变
性能要求极高的场景(中介者可能有性能开销)
八、总结:中介者模式的架构价值
在Spring Boot开发中,中介者模式带来三大核心价值:
1. 解耦革命:对象间不再直接依赖
2. 逻辑集中:交互规则统一管理
3. 灵活扩展:新增交互不影响现有代码
优秀架构的本质不是消除复杂性,而是管理复杂性!
中介者模式正是这种理念的完美体现,它让我们能够:
将混乱的网状依赖变为清晰的星型结构
集中管理业务规则和交互逻辑
轻松应对业务变化和扩展需求
行动建议:当你的系统中出现以下信号时,考虑引入中介者模式:
对象间交互复杂,关系混乱
修改一个对象会影响多个其他对象
对象间通信逻辑分散在各处
添加新功能需要修改多个类
掌握中介者模式,让你的系统从"蜘蛛网"进化为"高速公路",实现真正的优雅架构!
架构设计之道在于在不同的场景采用合适的架构设计,架构设计没有完美,只有合适。
在代码的路上,我们一起砥砺前行。用代码改变世界!
如果有其它问题,欢迎评论区沟通。
感谢观看,如果觉得对您有用,还请动动您那发财的手指头,点赞、转发、在看、收藏。
高并发解决方案与架构设计。
海量数据存储和性能优化。
通用框架/组件设计与封装。
如何设计合适的技术架构?
如何成功转型架构设计与技术管理?
在竞争激烈的大环境下,只有不断提升核心竞争力才能立于不败之地。