设计模式之~观察者模式

news2024/11/19 11:21:25

        观察者模式又叫做发布-订阅(Publish/Subscribe)模式。

        观察者模式observer:定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

        观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖与抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

观察者模式的动机:
        将一个系统分割成一系列相互协作的类有一个很不好的副作用那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。

结构图:

Subjec类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个接口实现。它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个Update()方法,这个方法叫做更新方法。

ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

实例图:

优点:

  • 建立一套触发机制。

  • Subject和Observer之间是松偶合的,分别可以各自独立改变。

  • Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。

  • 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。观察者和被观察者是抽象耦合的。

缺点:

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。提高时间消耗及程序的复杂度

  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

  • 尽管已经用了依赖倒转原则,但是‘抽象通知者’还是依赖‘抽象观察者’,也就是说,万一没有了抽象观察者这样的接口,通知的功能就完不成了。【“抽象通知者”由于不希望依赖“抽象观察者”】

  • 另外就是每个具体观察者,收到通知时,要调用的接口并不一定一致。

适用场景:

        当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。

        当一个抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将者两者封装在独立的对象中使它们各自独立地改变和复用。

        观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。这其实是依赖倒转原则的最佳体现。

委托:

        委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。

        委托可以看做是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。

        一个委托可以搭载多个方法,所有方法被依次唤起。可以使得委托对象所搭载的方法并不需要属于同一个类。

        这样就使得,本来是在‘通知者’类中的增加和减少的抽象观察者集合以及通知时遍历的抽象观察者都不必要了。转到客户端让委托搭载多个方法,这就解决了本来与抽象观察者耦合的问题。

        但委托也是由前提的,那就是委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型。注意,是先有观察者模式,再有委托事件技术的,它们各有优缺点。

事件委托实例:

“看股票观察者”类和“看NBA观察者”类,去掉了父类“抽象观察类”,所以补上一些代码,并将“更新”方法名改为各自适合的方法名。

现实中就是这样的,方法名本就不一定相同。
“抽象通知者”由于不希望依赖“抽象观察者”,所以“增加”和“减少”的方法也就没有必要了(抽象观察者已经不存在了)

下面就是如何处理‘老板’类和‘前台’类的问题。声明一个委托,名叫“EventHandler(事件处理程序)”,无参数,无返回值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/591770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《计算机组成原理》唐朔飞 第8章 CPU的结构和功能 - 学习笔记

写在前面的话:此系列文章为笔者学习计算机组成原理时的个人笔记,分享出来与大家学习交流。使用教材为唐朔飞第3版,笔记目录大体与教材相同。 网课 计算机组成原理(哈工大刘宏伟)135讲(全)高清_…

实现分布式实体追踪:提升系统可见性和故障排查能力

引言: 在当今复杂的分布式系统中,追踪用户请求的执行过程变得越来越重要。为了获得全面的系统可见性和更高效的故障排查能力,我们在Flipkart采用了分布式实体追踪的解决方案。本文将介绍我们的实施策略,以及如何使用结构化日志和集…

IMG CXM GPU:面向复杂消费级设备的无缝视觉体验

上周我们推出了一款新的GPU,即IMG CXM。它的三种配置可扩展,为可穿戴设备和高级数字电视等多种消费设备提供无缝用户界面。 消费级设备需要GPU提供什么? 涵盖智能手表和智能眼镜的可穿戴市场为移动中的消费者提供了易于访问的信息。鉴于屏幕尺…

一文解读 AIGC 驱动高绩效商业的落地与思考

本文根据神策数据智能业务负责人郭荣锋《AIGC 驱动高绩效商业的实践》的主题演讲整理所得,主要围绕神策对 AIGC (即 AI-Generated Content,人工智能生成内容)业务应用的理解、AIGC 的落地实践及心得体会等方面展开。 以下为本文的…

运行 100 万个并发任务究竟需要多少内存?

Laf 公众号已接入了 AI 绘画工具 Midjourney&#xff0c;可以让你轻松画出很多“大师”级的作品。同时还接入了 AI 聊天机器人&#xff0c;支持 GPT、Claude 以及 Laf 专有模型&#xff0c;可通过指令来随意切换模型。欢迎前来调戏&#x1f447; <<< 左右滑动见更多 &…

Tomcat文件夹属性

Tomcat安装完成后&#xff0c;其安装目录下包含bin、conf、lib、logs、temp、webapps、work等子目录&#xff0c;各个子目录简介如下&#xff1a; &#xff08;1&#xff09;bin目录。主要存放Tomcat的命令文件。&#xff08;解压缩版点击bin下的startup.bat&#xff0c;即可运…

4.2 字节流与字符流

在Java中&#xff0c;有两种基本的数据流类型&#xff1a;字节流和字符流。字节流处理原始二进制数据&#xff0c;而字符流处理Unicode字符。本章节我们将学习字节流与字符流的基本概念以及如何使用它们进行文件的输入输出操作。 4.2.1 字节流 字节流处理原始二进制数据&…

打造音视频极致消费体验

在观看视频时&#xff0c;用户最看重的是什么呢&#xff1f;清晰度&#xff1f;流畅度&#xff1f;还是播放时的稳定性&#xff1f;作为视频厂商&#xff0c;不仅要考虑到常见的指标&#xff0c;一些关乎用户体验的隐藏性指标也需要重点关注。如何持续升级优化代码并在成本和用…

JointJS+ v3.7 Crack

JointJS v3.7 改进了对 SVG 上下文中的外部对象的支持。 2023 年 5 月 30 日 - 16:00 新版本 特征 改进了对外部对象 (HTML) 的支持- 外部对象已成为 Web 开发的标准&#xff0c;JointJS 现在已经在 SVG 上下文中引入了对外部对象的全面且功能齐全的支持。这意味着您现在可以在…

工作积极主动分享,善于业务沟通

工作积极主动分享&#xff0c;善于业务沟通 目录概述需求&#xff1a; 设计思路实现思路分析1.工作积极主动承担责任2.善于沟通3.一起常常lauch 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;…

【JavaSE】Java基础语法(三十九):网络编程入门

文章目录 1. 网络编程概述2. 网络编程三要素3. IP地址4. InetAddress5. 端口和协议 1. 网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络 操作系统&#xff0c;网络管理软件及网络通信协…

MyBatis 环境搭建+基本使用

目录 MyBatis创建MyBatis环境搭建MyBatis模式开发MyBatis 获取动态参数&#xff08;查询操作&#xff09;${} 直接替换#{} 占位符模式替换like查询&#xff08;模糊查询&#xff09;多表查询一对一的表映射一对多的表映射 增、删、改操作改操作删除操作增加操作添加用户添加用户…

chatgpt赋能python:Python中的英文单词

Python中的英文单词 Python是一种流行的编程语言&#xff0c;它具有人类易读性、功能强大、支持多种编程范例等特点。Python中包含着大量的英文单词&#xff0c;这些单词在Python编程中极为重要&#xff0c;因为它们直接影响代码的可读性和理解难度。本文将介绍一些最常用的Py…

Go开发学习 | 如何使用Gomail.v2模块包发送邮箱验证码消息及附件学习记录

欢迎关注「全栈工程师修炼指南」公众号 点击 &#x1f447; 下方卡片 即可关注我哟! 设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01; “ 花开堪折直须折&#xff0c;莫待无花空折枝。 ” 作者主页&#xff1a;[ https://www.weiyigeek.top ] 博客&…

vulhub-Jarbas(易)

打靶练习Jarbas 0x00 部署0x01 信息收集&#xff1a;端口扫描、服务发现0x02 路径爬取0x03 反弹shell0x04 内网信息收集0x05 crontab定时任务提权0x06 总结 0x00 部署 靶机&#xff1a;下载地址 宿主机&#xff1a;kali2021版本 0x01 信息收集&#xff1a;端口扫描、服务发现…

《计算机组成原理》唐朔飞 第9章 控制单元的功能 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习计算机组成原理时的个人笔记&#xff0c;分享出来与大家学习交流。使用教材为唐朔飞第3版&#xff0c;笔记目录大体与教材相同。 网课 计算机组成原理&#xff08;哈工大刘宏伟&#xff09;135讲&#xff08;全&#xff09;高清_…

git (本地仓库)和(远程仓库)之间的代码推送:013

这里先说明一下循序&#xff1a; 1. 创建(远程仓库)和(本地仓库) 2. 创建(远程仓库)和(本地仓库)之间的链接 3. 将(本地仓库)的代码推通过命令送到(远程仓库)&#xff1b;将(本地仓库)的代码通过(TortoiseGit小乌龟)推送到(远程仓库) 1. 创建(远程仓库)和(本地仓库)&#xff0c…

PHP异步:在PHP中使用 fsockopen curl 实现类似异步处理的功能

PHP从主流来看&#xff0c;是一门面向过程的语言&#xff0c;它的最大缺点就是无法实现多线程管理&#xff0c;其程序的执行都是从头到尾&#xff0c;按照逻辑一路执行下来&#xff0c;不可能出现分支&#xff0c;这一点是限制php在主流程序语言中往更高级的语言发展的原因之一…

C++实现sqlite单表增删改查的详细步骤

1.环境准备 coding之前需要先安装好C的集成开发环境&#xff0c; 我这里选择的是Visual Studio 2022&#xff0c;本来想使用CLion的&#xff0c; 但是破解太麻烦&#xff0c;懒得整了。 Visual Studio 2022 2.项目创建及编码 启动visual studio, 点击创建项目&#xff0c;选…

《MYSQL必知必会》读书笔记1

目录 行 主键 MYSQL工具 使用MYSQL 连接 检索数据 检索&#xff08;SELECT&#xff09; 限制结果&#xff08;LIMIT&#xff09; 排序检索&#xff08;ORDER BY&#xff09; 过滤数据&#xff08;WHERE&#xff09; 过滤数据&#xff08;AND、OR&#xff09; 通配符…