当前位置: 首页 > news >正文

Java设计模式之观察者模式:从入门到架构级实践

一、观察者模式的核心价值

观察者模式(Observer Pattern)是行为型设计模式中的经典之作,它建立了对象间的一对多依赖关系,让多个观察者对象能够自动感知被观察对象的状态变化。这种模式在事件驱动系统、实时数据推送、GUI事件处理等场景中广泛应用,是实现松耦合设计的利器。

核心价值体现

  • 解耦生产者(被观察者)与消费者(观察者)

  • 支持动态的观察者注册与注销

  • 实现广播通信机制

  • 符合开放-封闭原则(对扩展开放,对修改关闭)

二、模式结构深度解析

2.1 核心角色分解

  1. Subject(抽象主题)

    • 维护观察者列表(List<Observer>)

    • 提供观察者的注册(attach)和注销(detach)方法

    • 定义通知方法(notifyObservers)

  2. ConcreteSubject(具体主题)

    • 维护具体状态信息

    • 状态改变时调用父类的通知方法

    • 可提供获取状态的接口

  3. Observer(抽象观察者)

    • 定义更新接口(update方法)

  4. 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();}@Overridepublic void register(Observer o) { observers.add(o); }@Overridepublic void remove(Observer o) { observers.remove(o); }@Overridepublic void notifyObservers() {for (Observer o : observers) {o.update(temperature);}}
}// 抽象观察者
interface Observer {void update(float temp);
}// 具体观察者(手机显示)
class PhoneDisplay implements Observer {@Overridepublic 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 {@Overridepublic 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);}@Overridepublic void subscribe(Subscriber<? super Float> subscriber) {publisher.subscribe(subscriber);}
}class FlowDisplay implements Subscriber<Float> {private Subscription subscription;@Overridepublic void onSubscribe(Subscription s) {this.subscription = s;s.request(1);}@Overridepublic 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 {@Overridepublic 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));}
}

六、生产环境最佳实践

  1. 性能优化策略

    • 采用CopyOnWriteArrayList避免并发修改异常

    • 使用Guava的EventBus进行事件分发

    • 实现观察者优先级机制

    • 添加批处理通知功能

  2. 可靠性增强

    • 引入死信队列处理失败通知

    • 实现幂等性处理

    • 添加事务消息支持

    • 建立监控指标体系(QPS、失败率等)

  3. 扩展性设计

    • 支持观察者过滤器

    • 实现主题分组机制

    • 添加消息持久化能力

    • 支持跨进程观察(分布式观察者)

七、常见陷阱与解决方案

典型问题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))
    );

八、模式演进与变种

  1. 中介者模式结合

    • 通过中介者统一管理观察关系

    • 实现更复杂的消息路由

  2. 响应式扩展

    • 结合RxJava实现流式处理

    • 支持背压(Backpressure)机制

  3. 领域事件模式

    • 在DDD中应用观察者模式

    • 实现领域事件的发布/订阅

  4. CQRS架构集成

    • 将命令与查询分离

    • 通过观察者维护读模型

九、总结与展望

观察者模式作为解耦利器,在现代架构中展现出强大的生命力。随着响应式编程的兴起,观察者模式正在与以下新技术深度融合:

  1. 云原生架构:跨服务的观察者模式实现

  2. Serverless:事件驱动的函数计算

  3. 物联网(IoT):海量设备的状态同步

  4. 实时数据分析:流式计算中的事件处理

建议开发者根据具体场景选择合适的实现方式:

  • 简单场景:直接使用语言内置支持

  • 复杂系统:采用成熟的响应式框架(如RxJava、Reactor)

  • 分布式环境:使用消息中间件(如Kafka、RabbitMQ)

掌握观察者模式的精髓,将使你的系统架构具备更好的扩展性和灵活性,从容应对各种复杂的业务需求变化。

相关文章:

  • 安卓基础(SQLite)
  • 设计模式之状态模式:优雅管理对象行为变化
  • 最简单的使用SDL2 播放原始音频数据程序
  • KrillinAI:视频跨语言传播的一站式AI解决方案
  • js原型链污染
  • 使用 LLaMA-Factory 对 DeepSeek R1进行微调教程
  • Docker--Docker镜像原理
  • PHP4 Session定制与使用指南
  • 部署LLaMA Factory,及快速使用
  • 3DGS之渲染管线
  • 天元证券|8家汽车零部件上市公司一季度业绩预喜
  • [特殊字符] LoRA微调大模型实践:从MAC到Web的全流程指南
  • SGFormer:卫星-地面融合 3D 语义场景补全
  • 大模型预标注和自动化标注在OCR标注场景的应用
  • http、https、TLS、证书原理理解,对称加密到非对称加密问题,以及对应的大致流程
  • Linux驱动开发进阶(八)- GPIO子系统BSP驱动
  • 【Qt】初识Qt
  • 使用Python+xml+shutil修改目标检测图片和对应xml标注文件
  • Python 导出 PDF(ReportLab )
  • 【算法】椭圆曲线签名(ECDSA)
  • danbold做动漫的网站/百度竞价推广一个月多少钱
  • 怎样做视频网站/文库百度登录入口
  • 如何判断一个网站是恶意网站/武汉百度信息流广告
  • 做网站排名步骤/在线生成网站
  • 百捷网站建设工资/链接生成二维码
  • 网站字体设计重要性/痘痘该怎么去除效果好