设计模式行为型——观察者模式
目录
什么是观察者模式
观察者模式的实现
观察者模式角色
观察者模式类图
观察者模式举例
观察者模式代码实现
观察者模式的特点
优点
缺点
使用场景
注意事项
实际应用
什么是观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式的实现
观察者模式角色
- 主题角色(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
- 具体主题角色(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
- 观察者角色(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
- 具体观察者角色(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
观察者模式类图
观察者模式举例
观察者模式代码实现
主题角色
package com.common.demo.pattern.observer;import java.util.Vector;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 主题角色* @date 2023/08/07 10:37:05*/
public abstract class Subject {private Vector<Observer> obs = new Vector();public void addObserver(Observer obs) {this.obs.add(obs);}public void delObserver(Observer obs) {this.obs.remove(obs);}protected void notifyObserver() {for (Observer o : obs) {o.update();}}public abstract void doSomething();
}
具体主题角色
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体主题角色* @date 2023/08/07 10:39:23*/
public class ConcreteSubject extends Subject{@Overridepublic void doSomething(){System.out.println("被观察者事件发生改变");this.notifyObserver();}
}
观察者角色
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 观察者角色 观察者接口* @date 2023/08/07 10:30:26*/
public interface Observer {void update();
}
具体观察者角色
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体观察者角色 观察者角色A* @date 2023/08/07 10:40:54*/
public class ConcreteObserverA implements Observer{@Overridepublic void update() {System.out.println("观察者A收到信息,并进行业务处理");}
}
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体观察者角色 观察者角色B* @date 2023/08/07 10:40:54*/
public class ConcreteObserverB implements Observer{@Overridepublic void update() {System.out.println("观察者B收到信息,并进行业务处理");}
}
测试类
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 测试类* @date 2023/08/07 10:46:55*/
public class ClientTest {public static void main(String[] args) {Subject sub = new ConcreteSubject();sub.addObserver(new ConcreteObserverA());sub.addObserver(new ConcreteObserverB());sub.doSomething();}
}
测试截图
观察者模式的特点
优点
- 实现了松耦合:观察者模式可以将被观察者和观察者之间的耦合度降低,使得它们可以独立地进行扩展和修改。
- 支持广播通信:建立一套广播通信触发机制,被观察者可以同时通知多个观察者,从而支持广播通信的需求。
- 符合开闭原则:新增或删除观察者不会影响到被观察者和其他观察者的代码,符合开闭原则的要求。
缺点
- 观察者过多可能导致性能问题:如果观察者过多或者观察者的处理逻辑复杂,会影响到系统的性能,花费较多的时间。
- 观察者和被观察者直接关联:在一些情况下,观察者和被观察者之间的直接关联可能会导致设计上的困扰。
- 观察者和观察目标循环依赖:在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者对所观察的目标对象黑盒操作:无相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景
- 当一个对象的改变需要通知其他对象,并且不希望将对象之间的耦合度过高时,可以考虑使用观察者模式。
- 当某个对象的状态改变需要引起一系列相关对象的更新时,不需要知道这些对象是谁,不需知道具体有多少对象有待改变,可以使用观察者模式。
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
注意事项
- 注意观察者和被观察者的关联方式:可以通过接口或抽象类定义观察者接口,使得被观察者只与接口进行交互,而不依赖于具体的观察者实现类。
- 避免循环依赖:观察者和被观察者之间应该避免出现循环依赖的情况,否则可能导致无限循环的通知。
- 如果顺序执行,某一观察者错误会导致系统卡壳,可采用异步方式进行通知。
实际应用
- 网络订阅服务:订阅者可以订阅感兴趣的内容,当内容更新时,订阅者会收到通知。
- 消息中间件:多个消息消费者可以同时监听一个消息主题,当主题发布消息时,所有消费者都会接收到通知并处理消息。
- GUI界面组件:GUI界面中的事件监听机制就是一种观察者模式的实现。
更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)
相关文章:

设计模式行为型——观察者模式
目录 什么是观察者模式 观察者模式的实现 观察者模式角色 观察者模式类图 观察者模式举例 观察者模式代码实现 观察者模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是观察者模式 观察者模式(Observer Pattern)是一种行为型设计模式…...

Kernel Exception导致手机重启案例分析
和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 一、高温触发 Kernel Exception 重启问题二、解决方案三、提高电池温度方案 一、 高温触发 Kernel Exception 重启问题 手机 电池温度 默认60度以上高温…...

C++入门篇5---模板
相信大家都遇到过这么一种情况,为了满足不同类型的需求,我们要写多个功能相同,参数类型不同的代码,为此,C引入了泛型编程这一概念,而模板就是实现泛型编程的基础,其实本质就是我们写一个类似”模…...

L2CS-Net: 3D gaze estimation
L2CS-Net: Fine-Grained Gaze Estimation in Unconstrained Environments论文解析 摘要1. 简介2. Related Work3. METHOD3.1 Proposed loss function3.2 L2CS-Net 结构3.3 数据集3.4 评价指标 4. 实验4.1 实验结果 论文地址:L2CS-Net: Fine-Grained Gaze Estimation…...

kenernetes/k8s笔试面试
k8s的基础概念 k8s本质是一个容器编排系统,可以管理容器的生命周期,应用部署,更新,维护,应用提供服务,扩容缩容应用,故障自愈。 k8s与docker的关系 docker:是一种轻量级的虚拟化技术。运维层…...

我们真的是在做数据治理吗
我们真的是在做数据治理吗? 什么是数据治理? 数据治理和数据管理有什么区别? 相信即使是考过数据治理工程师的人,面对这2个问题也仍然会有这个疑问。 目前国际和国内对于数据治理没有明确统一的定义,对于数据治理的服…...

聊聊汽车电子的话题
当谈到汽车电子时,有许多有趣的话题可以探讨。以下是一些可能感兴趣的话题: 自动驾驶技术:自动驾驶技术正变得越来越先进,它们如何在汽车中实现?它们将如何改变我们的交通方式以及对道路安全的影响? 电动汽…...

ThinkPHP6企业OA办公系统
有需要请加文章底部Q哦 可远程调试 ThinkPHP6企业OA办公系统 一 介绍 勾股OA基于ThinkPHP6开发,前端Layui,数据库mysql,是一款实用的企业办公系统。可多角色登录,集成了系统设置、人事管理、消息管理、审批管理、日常办公、客户…...

PPS Tester测量原理和实施方法
怿星科技发布了新品PPS Tester,这是一款基于1PPS方法的时间同步精度测试设备。PPS Tester由硬件模块ETS2110和上位机软件ePPSTester构成。本文将围绕此设备的应用场景,介绍相关概念和设备使用方法。 什么是时间同步? 时间同步就是采取某项技…...

浅谈新电改背景下电网企业综合能源服务商业模式研究及发展方向
安科瑞 华楠 摘要: 新电改方案实施后,由于输配电价的改革和售电侧的放开,电网企业的盈利模式也随之发生了变化。这就要求电网企业转变服务理念与经营方式,来寻求竞争优势。基于“魏朱六要素商业模式”模型,对电网企业综合能源服务…...

SpringBoot + Docker 实现一次构建到处运行~
一、容器化部署的好处 图片 Docker 作为一种新兴的虚拟化方式,它可以更高效的利用系统资源,不需要进行硬件虚拟以及运行完整操作系统等额外开销。 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行…...

clang-format格式化代码
1. clang-format简介 Clang-Format可用于格式化(排版)多种不同语言的代码。其自带的排版格式主要有:LLVM, Google, Chromium, Mozilla, WebKit等; 利用style参数配置风格。通过编写 .clang-format 文件,可以实现代码风格的配置。…...

品牌宣传与媒体传播是声誉管理的主要方式之一
企业声誉是现如今影响品牌信任度、客户忠诚度的重要因素,也被视为企业的一种无形资,更影响着企业未来的发展。因此,企业声誉管理也日渐成为企业管理的重要课题之一,尤其在品牌营销管理领域。 什么是声誉管理?声誉管理有…...

2023年8月7日-8月13日,(上午熟悉公司代码,周一到周五晚上优先工作所急视频教程,其他业余时间进行ue视频教程,为独立游戏做准备)
按照规划,上午熟悉公司源码,下午进行filament和ue渲染,晚上写工作代码。回家后泛读pbrt或者其他书籍催眠。 业余学习ue的各种视频教程,为独立游戏做准备(公司也实行末位淘汰,给自己留条后路)。累…...

Vue3 第二节 Vue3的响应式
1.Vue3的响应式原理 2.ref函数和reactive函数的对比 3.setup注意点 一.Vue3的响应式原理 1.Vue2.x中的响应式原理 ① 实现原理 对象类型:通过Object.defineProperty() 对属性的读取,修改进行拦截(数据劫持)数组类型…...

通过easyui实现动态控制表格字段显示、导出表格数据
前言 学过layui前端框架的都知道,layui默认帮我们实现了控制表格字段显示以及数据的导出功能。 1、控制表格字段显示 2、数据导出 3、导出为pdf:导出按钮的右边那个按钮就是打印pdf的 那么,easyui要怎么实现这些功能呢?这篇文章就…...

JWT入门,jwt可以解密吗?
JWT 什么是 JWT JSON Web Token,通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全地传输信息 官网:https://jwt.io/SDK: https://jwt.io/libraries (含Java和各种语言)Java SDK(上面的SDK链接得到): https://g…...

36.利用解fgoalattain 有约束多元变量多目标规划问题求解(matlab程序)
1.简述 多目标规划的一种求解方法是加权系数法,即为每一个目标赋值一个权系数,把多目标模型转化为一个单目标模型。MATLAB的fgoalattain()函数可以用于求解多目标规划。 基本语法 fgoalattain()函数的用法: x fgoalattain(fun,x0,goal,weig…...

EPPlus 读取和生成Excel
在项目中添加了EPPlus库的引用,你可以通过NuGet包管理器或手动将EPPlus库添加到项目中。同时,需要注意的是EPPlus库支持的是xlsx格式的Excel文件。 读取 使用EPPlus读取本地Excel文件的示例代码如下: using OfficeOpenXml;public void Rea…...

Java wait() notify() join()用法讲解
一、wait() 1. 源码: 实际调用本地方法 2. 作用 释放当前锁,并让当前线程进入等待状态;timeoutMillis为等待时间,单位毫秒,如果为0则表示无限等待下去;该方法使用前提是:当前执行线程必须持…...

新手注意事项-visual studio 来实现别踩白块儿
自己之前为了熟悉easyx练习过一个简单的项目,别踩白块儿,链接在这里,别踩白块儿,当时比较稚嫩,很多东西都不会,可以说是只知道最基本的语法,头文件都不知道,一个一个查资料弄懂的&am…...

【力扣】2810. 故障键盘 <模拟>
【力扣】2810. 故障键盘 你的笔记本键盘存在故障,每当你在上面输入字符 ‘i’ 时,它会反转你所写的字符串。而输入其他字符则可以正常工作。给你一个下标从 0 开始的字符串 s ,请你用故障键盘依次输入每个字符。返回最终笔记本屏幕上输出的字…...

Docker desktop使用配置
1. 下载安装 https://www.docker.com/ 官网下载并安装doker desktop 2. 配置镜像 (1)首先去阿里云网站上进行注册:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors (2)注册完成后搜索:容…...

第一百二十一天学习记录:线性代数:矩阵乘法运算(宋浩板书)
在编程和学习数据结构的过程中,发现有些算法会用到矩阵和矩阵的乘法运算,因此先将这一个知识点学习一下。 矩阵和行列式的区别 各种矩阵的概念 矩阵运算 乘法☆ 总结三条不满足...

模拟实现消息队列项目(系列3) -- 服务器模块(硬盘管理)
目录 前言 1. 创建项目 2. 创建核心类 2.1 Exchange 2.2 MSQueue 2.3 Binding 2.4 Message 3. 数据库设计 3.1 SQLite 配置 3.2 Mapper层代码实现 3.2.1 创建表操作 3.2.2 交换机 队列 绑定的增加和删除 3.3 实现DataBaseManager 3.4 DataBaseManager单元测试 4.…...

【iOS】锁
线程安全 当一个线程访问数据的时候,其他的线程不能对其进行访问,直到该线程访问完毕。简单来讲就是在同一时刻,对同一个数据操作的线程只有一个。而线程不安全,则是在同一时刻可以有多个线程对该数据进行访问,从而得…...

杰发科技(合肥)2021笔试题
笔试时间:2020.10.17 ,10:30-12:00。 岗位:Linux 驱动工程师。 题型:选择题8道,填空题10道,编程题4道。 杰发科技主要做汽车电子,由北京四维图新控股,对汽车电子感兴趣的有机会可以应聘试试。 选择题 1、128,4 #include<stdio.h> unsigned int getstrsiz…...

Java堆排序
目录 PriorityQueue自己实现 PriorityQueue public class PriorityQueueMain {public static void main(String[] args) {int[] temp {40, 2, 33, 26, 35, 8, 8, 26, 29, 2};PriorityQueue<Integer> priorityQueue new PriorityQueue<>();for (int i 0; i <…...

GitHub的基本使用教程
GitHub是一个基于web的版本控制和协作平台。它允许开发人员将他们的代码存储库存储在云中,并与其他人一起进行工作。GitHub还提供了各种工具和功能来帮助开发人员管理和组织他们的代码项目,包括拉出请求、问题跟踪、代码评论等等。此外,它托管…...

objectMapper.configure 方法的作用和使用
objectMapper.configure 方法是 Jackson 提供的一个用于配置 ObjectMapper 对象的方法。ObjectMapper 是 Jackson 库的核心类,用于将 Java 对象与 JSON 数据相互转换。 configure 方法的作用是设置 ObjectMapper 的配置选项,例如设置日期格式、设置序列…...