一、观察者模式的核心价值
观察者模式(Observer Pattern)是行为型设计模式中的经典之作,它建立了对象间的一对多依赖关系,让多个观察者对象能够自动感知被观察对象的状态变化。这种模式在事件驱动系统、实时数据推送、GUI事件处理等场景中广泛应用,是实现松耦合设计的利器。
核心价值体现:
-
解耦生产者(被观察者)与消费者(观察者)
-
支持动态的观察者注册与注销
-
实现广播通信机制
-
符合开放-封闭原则(对扩展开放,对修改关闭)
二、模式结构深度解析
2.1 核心角色分解
-
Subject(抽象主题)
-
维护观察者列表(List<Observer>)
-
提供观察者的注册(attach)和注销(detach)方法
-
定义通知方法(notifyObservers)
-
-
ConcreteSubject(具体主题)
-
维护具体状态信息
-
状态改变时调用父类的通知方法
-
可提供获取状态的接口
-
-
Observer(抽象观察者)
-
定义更新接口(update方法)
-
-
ConcreteObserver(具体观察者)
-
实现具体的更新逻辑
-
可持有主题引用以获取更多状态信息
-
2.2 两种通知模型对比
模型类型 | 数据传递方式 | 优点 | 缺点 |
---|---|---|---|
推模型 | 主题主动推送详细数据给观察者 | 实时性强,响应快 | 可能传递冗余数据 |
拉模型 | 观察者收到通知后主动拉取数据 | 按需获取,灵活性高 | 增加主题的访问压力 |
三、基础实现代码示例
3.1 自定义实现版本
// 抽象主题
interface Subject {
void register(Observer o);
void remove(Observer o);
void notifyObservers();
}
// 具体主题(气象站)
class WeatherStation implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature;
public void setMeasurements(float temp) {
this.temperature = temp;
notifyObservers();
}
@Override
public void register(Observer o) { observers.add(o); }
@Override
public void remove(Observer o) { observers.remove(o); }
@Override
public void notifyObservers() {
for (Observer o : observers) {
o.update(temperature);
}
}
}
// 抽象观察者
interface Observer {
void update(float temp);
}
// 具体观察者(手机显示)
class PhoneDisplay implements Observer {
@Override
public void update(float temp) {
System.out.println("手机显示温度更新:" + temp + "℃");
}
}
3.2 Java内置实现
Java自带的java.util.Observable
类和Observer
接口:
class WeatherData extends Observable {
private float temperature;
public void measurementsChanged() {
setChanged(); // 必须调用此方法
notifyObservers();
}
public void setMeasurements(float temp) {
this.temperature = temp;
measurementsChanged();
}
// 供观察者拉取数据
public float getTemperature() {
return temperature;
}
}
class TVDisplay implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherData) {
WeatherData wd = (WeatherData) o;
System.out.println("电视显示当前温度:" + wd.getTemperature());
}
}
}
四、高级架构实践
4.1 异步观察者模式
ExecutorService executor = Executors.newCachedThreadPool();
class AsyncNotifier {
public void notifyAsync(List<Observer> observers) {
observers.forEach(observer ->
executor.submit(() -> observer.update())
);
}
}
注意事项:
-
线程安全性问题
-
通知顺序无法保证
-
异常处理机制
-
资源释放管理
4.2 基于Java Flow的响应式实现
Java 9+ 引入的响应式流API:
class TemperaturePublisher implements Publisher<Float> {
private final SubmissionPublisher<Float> publisher =
new SubmissionPublisher<>();
public void publish(float temp) {
publisher.submit(temp);
}
@Override
public void subscribe(Subscriber<? super Float> subscriber) {
publisher.subscribe(subscriber);
}
}
class FlowDisplay implements Subscriber<Float> {
private Subscription subscription;
@Override
public void onSubscribe(Subscription s) {
this.subscription = s;
s.request(1);
}
@Override
public void onNext(Float temp) {
System.out.println("Flow显示温度:" + temp);
subscription.request(1);
}
}
五、典型应用场景
5.1 电商订单系统
class OrderService {
private List<OrderObserver> observers = new CopyOnWriteArrayList<>();
public void placeOrder(Order order) {
// 创建订单逻辑...
notifyObservers(order);
}
private void notifyObservers(Order order) {
observers.forEach(observer -> {
try {
observer.onOrderCreated(order);
} catch (Exception e) {
// 异常处理
}
});
}
}
interface OrderObserver {
void onOrderCreated(Order order);
}
// 库存扣减观察者
class InventoryObserver implements OrderObserver {
@Override
public void onOrderCreated(Order order) {
inventoryService.reduceStock(order.getItems());
}
}
5.2 微服务配置中心
@RestController
public class ConfigController {
private final ConfigSubject configSubject;
@PostMapping("/update-config")
public void updateConfig(@RequestBody Config newConfig) {
configSubject.updateConfig(newConfig);
}
}
@Service
class ConfigSubject {
private List<ConfigObserver> observers = new ArrayList<>();
private Config currentConfig;
public synchronized void updateConfig(Config newConfig) {
this.currentConfig = newConfig;
notifyObservers();
}
private void notifyObservers() {
observers.forEach(observer ->
observer.onConfigChanged(currentConfig)
);
}
}
六、生产环境最佳实践
-
性能优化策略
-
采用CopyOnWriteArrayList避免并发修改异常
-
使用Guava的EventBus进行事件分发
-
实现观察者优先级机制
-
添加批处理通知功能
-
-
可靠性增强
-
引入死信队列处理失败通知
-
实现幂等性处理
-
添加事务消息支持
-
建立监控指标体系(QPS、失败率等)
-
-
扩展性设计
-
支持观察者过滤器
-
实现主题分组机制
-
添加消息持久化能力
-
支持跨进程观察(分布式观察者)
-
七、常见陷阱与解决方案
典型问题1:内存泄漏
-
现象:观察者未及时注销导致无法回收
-
解决方案:
// 使用弱引用 class WeakObserver implements Observer { WeakReference<Observer> ref; public WeakObserver(Observer real) { this.ref = new WeakReference<>(real); } // 实现代理方法... }
典型问题2:循环通知
-
现象:A通知B,B又通知A导致死循环
-
解决方案:
class SafeSubject implements Subject { private boolean notifying = false; public void notifyObservers() { if (notifying) return; notifying = true; try { // 执行通知... } finally { notifying = false; } } }
典型问题3:性能瓶颈
-
现象:同步通知大量观察者导致响应延迟
-
解决方案:
// 分片异步通知 List<List<Observer>> shards = partition(observers, 10); shards.forEach(shard -> executor.execute(() -> shard.forEach(Observer::update)) );
八、模式演进与变种
-
中介者模式结合
-
通过中介者统一管理观察关系
-
实现更复杂的消息路由
-
-
响应式扩展
-
结合RxJava实现流式处理
-
支持背压(Backpressure)机制
-
-
领域事件模式
-
在DDD中应用观察者模式
-
实现领域事件的发布/订阅
-
-
CQRS架构集成
-
将命令与查询分离
-
通过观察者维护读模型
-
九、总结与展望
观察者模式作为解耦利器,在现代架构中展现出强大的生命力。随着响应式编程的兴起,观察者模式正在与以下新技术深度融合:
-
云原生架构:跨服务的观察者模式实现
-
Serverless:事件驱动的函数计算
-
物联网(IoT):海量设备的状态同步
-
实时数据分析:流式计算中的事件处理
建议开发者根据具体场景选择合适的实现方式:
-
简单场景:直接使用语言内置支持
-
复杂系统:采用成熟的响应式框架(如RxJava、Reactor)
-
分布式环境:使用消息中间件(如Kafka、RabbitMQ)
掌握观察者模式的精髓,将使你的系统架构具备更好的扩展性和灵活性,从容应对各种复杂的业务需求变化。