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

行为型设计模式——观察者模式

文章目录观察者模式结构实现特点观察者模式在软件系统中对象并不是孤立存在的一个对象行为的改变可能会导致一个或多个其他与之存在依赖关系行为发生改变它们之间将会产生联动“触一发而动百发”。为了更好的描述对象之间存在的这种一对多的联动产生了观察者模式Observer Pattern这一解决方案。场景使用的社交软件当关注的博主更新了内容会收到提示信息购买的商品被送到菜鸟驿站会收到驿站发送的提示信息订阅了报刊每天/每月都会收到新的报纸或者杂志观察者模式是一种软件设计模式其中一个称为主体的对象维护其依赖项列表称为观察者并通常通过调用其方法之一自动将任何状态更改通知它们。定义对象之间的一种一对多的依赖关系使得每当一个对象状态发生改变时其相关依赖对象都得到通知并被自动更新。在观察者模式中发生改变的对象称为观察目标而被通知的对象称为观察者一个观察目标可以对应多个观察者而且这些观察者之间可以没有任何相互联系可以根据需要增加和删除观察者使得系统更易于扩展。观察者模式的别名包括发布-订阅Publish/Subscribe模式、模型-视图Model/View模式、源-监听器Source/Listener模式、从属者Dependents模式。结构在观察者模式结构图中包含如下几个角色Subject目标目标又称为主题它是指被观察的对象。在目标中定义了一个观察者集合一个观察目标可以接受任意数量的观察者来观察它提供一系列方法来增加和删除观察者对象同时它定义了通知方法notify()。目标类可以是接口也可以是抽象类或具体类。ConcreteSubject具体目标具体目标是目标类的子类通常它包含有经常发生改变的数据当它的状态发生改变时向它的各个观察者发出通知同时它还实现了在目标类中定义的抽象业务逻辑方法。如果无须扩展目标类则具体目标类可以省略。Observer观察者观察者将对观察目标的改变做出反应观察者一般定义为接口该接口声明了更新数据的方法update()因此又称为抽象观察者。Concrete Observer具体观察者在具体观察者中维护一个指向具体目标对象的引用它存储具体观察者的有关状态这些状态需要和具体目标的状态保持一致它实现了在抽象观察者Observer中定义的update()方法。通常在实现时可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。实现// 声明订阅者类, 只是做了声明, 并没有包含这个类的头文件classObserver;// 新闻社classNewsAgency{public://添加一个订阅者到list 容器中voidattach(Observer*ob){m_list.push_back(ob);}//从list 容器中删除一个订阅者voiddeatch(Observer*ob){m_list.remove(ob);}//将通知信息发送给list 容器中的所有订阅者virtualvoidnotify(string msg)0;virtual~NewsAgency(){};protected:// 订阅者列表,将所有的订阅者对象存储到STL的list 容器中listObserver*m_list;};// 摩根斯的新闻社classMorgans:publicNewsAgency{public:voidnotify(string msg)override;};voidMorgans::notify(string msg){cout摩根斯新闻社报纸的订阅者一共有m_list.size()人endl;for(constautoitem:m_list){item-update(msg);// 订阅者类的定义在下面}}// 八卦新闻classGossip:publicNewsAgency{public:voidnotify(string msg)override;};voidGossip::notify(string msg){cout八卦新闻社报纸的订阅者一共有m_list.size()人endl;for(constautoitem:m_list){item-update(msg);}}#pragmaonce#includestring#includeiostream#includeNewsAgency.husingnamespacestd;// 抽象的订阅者类classObserver{public://通过发布者对象将观察者对象存储了起来这样就可以收到发布者推送的消息了。Observer(string name,NewsAgency*news):m_name(name),m_news(news){m_news-attach(this);}//观察者取消订阅取消之后将不再接收订阅消息。voidunsubscribe(){m_news-deatch(this);}//观察者得到最新消息之后用于更新自己当前的状态。virtualvoidupdate(string msg)0;virtual~Observer(){}protected:string m_name;NewsAgency*m_news;};classDragon:publicObserver{public:usingObserver::Observer;voidupdate(string msg)override{cout路飞的老爸革命军龙收到消息: msgendl;}};classShanks:publicObserver{public:usingObserver::Observer;voidupdate(string msg)override{cout路飞的引路人红发香克斯收到消息: msgendl;}};classBartolomeo:publicObserver{public:usingObserver::Observer;voidupdate(string msg)override{cout路飞的头号粉丝巴托洛米奥收到消息: msgendl;}};intmain(){Morgans*msnewMorgans;Gossip*gossipnewGossip;Dragon*dragonnewDragon(蒙奇·D·龙,ms);Shanks*shanksnewShanks(香克斯,ms);Bartolomeo*bartonewBartolomeo(巴托洛米奥,gossip);ms-notify(蒙奇·D·路飞成为新世界的新的四皇之一, 赏金30亿贝里!!!);coutendl;gossip-notify(女帝汉库克想要嫁给路飞, 给路飞生猴子, 哈哈哈...);deletems;deletegossip;deletedragon;deleteshanks;deletebarto;return0;}特点⚠️观察者模式是一种使用频率非常高的设计模式无论是移动应用、Web应用或者桌面应用观察者模式几乎无处不在它为实现对象之间的联动提供了一套完整的解决方案凡是涉及到一对一或者一对多的对象交互场景都可以使用观察者模式。主要优点观察者模式可以实现表示层和数据逻辑层的分离定义了稳定的消息更新传递机制并抽象了更新接口使得可以有各种各样不同的表示层充当具体观察者角色。观察者模式支持广播通信观察目标会向所有已注册的观察者对象发送通知简化了一对多系统设计的难度。观察者模式满足“开闭原则”的要求增加新的具体观察者无须修改原有系统代码在具体观察者与观察目标之间不存在关联关系的情况下增加新的观察目标也很方便。主要缺点如果一个观察目标对象有很多直接和间接观察者通知所有的观察者会花费很多时间。如果在观察者和观察目标之间存在循环依赖观察目标会触发它们之间进行循环调用可能导致系统崩溃。观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的而仅仅只是知道观察目标发生了变化。适用环境当一个对象状态的改变需要改变其他对象时可使用观察者模式。需要在系统中创建一个触发链A对象的行为将影响B对象B对象的行为将影响C对象……可以使用观察者模式创建一种链式触发机制。
http://www.gsyq.cn/news/1368641.html

相关文章:

  • Web文件上传漏洞深度解析:从upload-labs靶场到真实渗透实战
  • Java 零基础全套教程,File 类与 IO 流,笔记 175-176
  • 终极指南:gwasglue如何让GWAS数据分析像拼积木一样简单
  • 在自动化测试场景中利用Taotoken多模型API提升用例生成效率
  • 明日方舟游戏素材开源资源库:1000+高清立绘与数据一键获取
  • OpenClaw 用户如何通过 Taotoken 配置实现 Agent 工作流的快速接入与运行
  • 为OpenClaw配置Taotoken作为OpenAI兼容供应商的完整流程
  • API 中转站接入实战:用词元无忧 API 快速替换 OpenAI 调用
  • 别再只看BLEU分数了:Gemini代码生成能力专业评测框架(覆盖语义正确性、上下文感知度、调试友好性3大稀缺指标)
  • 通达信ChanlunX缠论插件:5分钟完成专业缠论分析的终极免费工具
  • 终极指南:如何使用AdvancedSessionsPlugin快速构建UE4多人游戏联机系统
  • 魔兽争霸III地图制作新选择:HiveWE完全指南与实战技巧
  • MLOmics基准框架:标准化多组学数据预处理与机器学习实战指南
  • LOSEHU固件:解锁泉盛UV-K5/K6对讲机卫星通信与频谱分析潜能
  • 你的 CI/CD 为什么越来越慢?很多团队根本不是在“持续交付”,而是在“持续等待”
  • 空间数据建模新思路:基于高斯过程与Vecchia近似的去相关预处理方法
  • 让Realtek RTL8125网卡在VMware ESXi 6.7上重获新生:完整驱动编译与部署指南
  • VMware Workstation Pro 17上玩转华为openEuler 23.03:保姆级避坑与性能调优全记录
  • 毫米波生命体征监测终极指南:如何用开源项目实现8.6米非接触式健康监测?
  • ComfyUI-WanVideoWrapper深度解析:14B参数AI视频生成实战指南
  • 基于递归解耦与机器学习的高维带跳随机微分方程高效求解
  • 嵌入式开发 10 大经典硬件 BUG + 定位解决(15 年工程师踩坑实录)
  • OmenSuperHub终极指南:5分钟解锁惠普游戏本全部性能
  • 量子几何机器学习:子黎曼几何与Cartan分解实现时间最优控制
  • 手把手教你用SSH命令行升级ESXi 7.0到7.0U3,附老服务器CPU警告的解决方法
  • Dock布局系统:为Avalonia应用打造专业级多窗口界面
  • 在OpenClaw Agent工作流中集成Taotoken实现多模型决策能力
  • NVIDIA Profile Inspector深度教程:解锁显卡隐藏设置的终极指南
  • 电信数智版Wireshark 3.7.1:深度支持TLCP与国密算法的协议分析利器
  • Appium 2.10.1环境搭建实战:JDK21+Android SDK34全链路排障指南