观察者模式
1|0基本介绍
观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)
意图:当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。
观察者模式属于行为型模式, 大多应用于一些事件驱动模型(Spring涉及)或者游戏开发领域。
假设有一家气象局,姑且就叫神盾气象局吧,该气象局委托我们构建一套系统,这个系统有两个公告牌,需要我们显示当前的实时天气和未来的天气预报。 当神盾气象局发布新的天气数据(WeatherData)后,两个公告牌上显示的天气数据务必实时更新。神盾气象局同时要求我们保证程序拥有足够的可扩展性,因为以后随时要新增其他的公告牌(如紧急公告等)。
他们最初始的设计如下:
然鹅每当我需要删除或者新增公告牌时,我就必须得修改 核心逻辑代码,如此看来扩展性极差,违背了开闭原则(对扩展开放,对修改关闭)
从上述方案,我们已经大致了解该方案有很多问题
- 扩展性较差
- 代码功能耦合严重
- 核心功能代码改来改去容易出问题
2|0观察者模式
观察者模式通常情况所解决的需求场景:A对象(观察者)被 B对象(被观察者)的某种变化高度敏感,需要在B变化的那一刻A及时得到反馈。
举个例子:小明过马路,小明需要在红绿灯由红灯变成绿灯后到达马路另一侧,这个场景中,小明是观察者,红绿灯是被观察者,当红绿灯发生颜色改变时,小明需要得到反馈。
但是程序中的观察和现实中所说的【观察】有些许差异:
- 观察者不需要时刻盯着被观察者(小明不需要每一秒盯着红绿灯)
- 采用注册或者订阅(Subscribe)的方式告诉被观察者(红绿灯变色后会广播,小明可以听到)
采取这样被动的观察方式,省去了反复检索状态的资源消耗,也能得到最快的反馈速度,其实就是由拉变成了推。
观察者模式通常基于 Subject(主题)和 Observer(观察者)而设计,类图如下
既然我们说了神盾气象局最初的设计 多么的糟糕,那么我们现在就用观察者模式来重构它吧!
首先我们基于上述的通用类图,重新构建神盾气象局的结构类图以及编码实现
主题接口
观察者接口
公告牌接口
气象数据Entity
气象数据(被观察者)- 核心
显示当前天气的公告牌(CurrentConditionDisplay)
显示未来几天天气的公告牌(ForecastConditionDisplay)
到这里,我们整个神盾气象局的WeatherData应用就改造完成了。
两个公告牌 CurrentConditionsDisplay
和 ForecastConditionDisplay
实现了 Observer
和 DisplayElement
接口。在他们的构造方法中会调用 WeatherData
的 registerObserver
方法将自己注册成观察者,这样被观察者 WeatherData
就会持有观察者的应用,并将它们保存到一个集合中。当被观察者 WeatherData
状态发生变化时就会遍历这个集合,循环调用观察者更新公告牌数据的方法。后面如果我们需要增加或者删除公告牌,就只需要新增或者删除实现了 Observer
和 DisplayElement
接口的公告牌就好了。
好,我们接下来测试一下利用观察者模式改进后的程序.....
3|0观察者模式(JDK版)
我们还是用神盾气象局的例子来实现JDK版本的观察者模式,这样便于比较两者之间的差别
公告牌接口
气象数据Entity
气象数据(被观察者)- 核心
显示当前天气的公告牌(CurrentConditionDisplay)
显示未来几天天气的公告牌(ForecastConditionDisplay)
到这里,我们使用JDK自带的API实现了观察者模式,下面我们开始测试
输出结果
总结:使用JDK自带的API去实现观察者模式固然方便,但是由于需要继承 Observable
接口,会对被观察者类造成限制(单继承的局限性),其次 Observable
的代码 从属JDK1.0,底层还是用的相关的Vector去做安全的集合容器,个人感觉还是有点过时了,个人还是倾向于自实现观察者模式。
__EOF__

本文链接:https://www.cnblogs.com/dwlovelife/p/13352651.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)