一,观察者模式的定义
观察者模式是一种行为型设计模式,又被称为"发布-订阅"模式,它定义了对象之间的一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。
观察者模式的关注点是对象之间的通信以及被观察对象的状态。
观察者模式在现实生活中的抽象实例:
报纸订阅:报纸的内容发生变化时,订阅了该报纸的读者们都会收到通知并阅读最新的内容。
股票投资:股票的价格发生波动时,投资者们会根据最新价格修改相应的投资决策。
天气预报:当天气发生变化时,订阅了该服务的用户们会收到通知。
网络论坛:当论坛中有新的帖子或回复出现时,论坛的用户们会收到通知并可以参与讨论。
二,观察者模式的结构
观察者模式主要包含以下组件:
1.被观察者(Subject):
被观察的对象,它的内部包含了观察者对象的集合,并提供了添加、通知和删除观察者对象的统一接口。
2.观察者(Observer):
接收Subject通知的对象,它订阅了Subject的状态,并提供了更新操作的统一接口。
3.具体的被观察者(ConcreteSubject):
包含Subject类接口的具体实现,维护了观察者的列表,自身状态发生变化时通知所有的观察者。
4.具体的观察者(ConcreteObserver):
包含Observer类接口的具体实现,提供了更新操作的具体实现细节,一旦收到Subject的通知便进行更新操作。
组件之间的工作步骤如下:
1.被观察者维护一个观察者的列表,并提供了管理和通知观察者的方法。
2.观察者与被观察者绑定(attach),并将自己添加到观察者列表中。
3.当被观察者的状态发生变化时,开始通知观察者,通知的方式一般是遍历观察者列表,遍历时会调用每个观察者的更新方法。
4.观察者完成具体的更新操作。
对应UML类图:
三,观察者模式代码样例
Demo1:subject只完成通知
运行结果:
Demo2:subject完成通知并传参
运行结果:
四,观察者模式的应用场景
事件驱动编程:GUI界面开发时,监听用户在界面的各种操作,如按钮点击、窗口关闭等。
监控服务开发:当系统状态发生变化时(例如磁盘空间不足),工具会收到通知。
消息队列开发:基于"消费者-生产者"模式进行通信,当消息队列中有新的消息时,消费者会收到通知。
五,观察者模式的优缺点
观察者模式的优点:
符合"开闭原则"的要求。
支持广播的通信方式。
支持事件驱动编程。
可以动态添加观察者,代码扩展性好。
观察者模式的缺点:
每次状态变化都要遍历所有观察者,性能开销大。
每次状态变化都要通知所有的观察者,通信时间变长。
观察者数量过多会使代码的可读性变差。
当有多个客户端操作观察者的删除时,会带来数据安全问题。
六,代码实战
Demo1:基于观察者模式实现的模拟时钟定时
运行结果:
Demo2:基于观察者模式实现的模拟天气预报
运行结果:
七,参考阅读
https://sourcemaking.com/design_patterns/observer
https://www.modernescpp.com/index.php/the-observer-pattern/
https://www.geeksforgeeks.org/observer-pattern-c-design-patterns/
https://refactoringguru.cn/design-patterns/observer