观察者模式 vs 发布订阅:CS-Notes行为型模式对比
你是否在学习设计模式时混淆过观察者模式(Observer Pattern)和发布订阅模式(Publish-Subscribe Pattern)?本文通过CS-Notes项目中的设计模式体系,从定义、实现到应用场景,一文厘清两种模式的核心差异,读完你将掌握:
- 两种模式的结构特征与实现方式
- 松耦合设计的关键区别
- 如何在实际开发中选择合适模式
核心概念与结构差异
观察者模式:紧耦合的直接通信
观察者模式定义了对象间一对多的依赖关系,当目标对象(Subject)状态变化时,所有依赖它的观察者(Observer)会自动收到通知并更新。
结构特点:
- 目标对象与观察者直接交互,无中间媒介
- 观察者需实现统一接口,目标对象维护观察者列表
图:观察者模式典型结构(项目资源:assets/column.png)
发布订阅模式:松耦合的间接通信
发布订阅模式通过事件总线(Event Bus)实现解耦,发布者(Publisher)发布事件时无需知道订阅者(Subscriber)是谁,订阅者也无需知道事件来源。
结构特点:
- 引入事件调度中心作为中间层
- 发布者和订阅者完全解耦,通过事件类型关联
实现方式对比
观察者模式实现(基于CS-Notes设计原则)
// 目标接口
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 观察者接口
public interface Observer {
void update(String message);
}
// 具体目标实现
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state); // 直接调用观察者方法
}
}
}
代码参考:面向对象设计原则
发布订阅模式实现(事件总线扩展)
public class EventBus {
private Map<String, List<Subscriber>> subscriberMap = new HashMap<>();
public void subscribe(String eventType, Subscriber subscriber) {
subscriberMap.computeIfAbsent(eventType, k -> new ArrayList<>()).add(subscriber);
}
public void publish(String eventType, Object data) {
List<Subscriber> subscribers = subscriberMap.getOrDefault(eventType, Collections.emptyList());
for (Subscriber subscriber : subscribers) {
subscriber.onEvent(data); // 通过事件类型间接通知
}
}
}
实现思路:系统设计基础
关键差异对比表
| 维度 | 观察者模式 | 发布订阅模式 |
|---|---|---|
| 耦合程度 | 目标与观察者紧耦合 | 发布者与订阅者完全解耦 |
| 通信方式 | 直接调用 | 间接通过事件中心 |
| 适用场景 | 单一应用内部状态同步 | 跨模块/跨系统消息传递 |
| 灵活性 | 低(观察者需实现统一接口) | 高(支持动态事件类型) |
| 项目应用 | Java容器 | 消息队列 |
典型应用场景分析
观察者模式:GUI组件交互
在Swing等UI框架中,按钮(目标)与监听器(观察者)的交互是典型案例。当按钮被点击时,所有注册的ActionListener会立即收到通知。
项目关联:设计模式目录中的行为型模式章节。
发布订阅模式:分布式系统通信
在微服务架构中,服务间通过消息队列(如RabbitMQ)实现异步通信,服务A发布"订单创建"事件后,物流服务、通知服务等订阅者可独立处理业务。
项目关联:分布式系统设计中的事件驱动架构。
如何选择:决策流程图
总结与实践建议
- 优先使用发布订阅模式:在大多数业务场景下,通过事件总线(如Guava EventBus)实现的松耦合设计更利于扩展。
- 简化实现参考:CS-Notes项目的代码风格规范建议,优先使用JDK内置的
Observable类简化观察者模式实现。 - 避免过度设计:单一模块内简单的状态同步场景,无需引入复杂的事件中心,直接使用观察者模式更高效。
收藏本文,关注CS-Notes项目获取更多设计模式实践指南,下期将解析"装饰器模式与代理模式的实战区别"。

项目主页:README.md
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



