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

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

目录

什么是观察者模式

观察者模式的实现

观察者模式角色

观察者模式类图

观察者模式举例

观察者模式代码实现

观察者模式的特点

优点

缺点

使用场景

注意事项

实际应用


什么是观察者模式

        观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式的实现

观察者模式角色

  1. 主题角色(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
  2. 具体主题角色(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
  3. 观察者角色(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
  4. 具体观察者角色(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();}
}

测试截图

观察者模式的特点

优点

  1. 实现了松耦合:观察者模式可以将被观察者和观察者之间的耦合度降低,使得它们可以独立地进行扩展和修改。
  2. 支持广播通信:建立一套广播通信触发机制,被观察者可以同时通知多个观察者,从而支持广播通信的需求。
  3. 符合开闭原则:新增或删除观察者不会影响到被观察者和其他观察者的代码,符合开闭原则的要求。

缺点

  1. 观察者过多可能导致性能问题:如果观察者过多或者观察者的处理逻辑复杂,会影响到系统的性能,花费较多的时间。
  2. 观察者和被观察者直接关联:在一些情况下,观察者和被观察者之间的直接关联可能会导致设计上的困扰。
  3. 观察者和观察目标循环依赖:在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 
  4. 观察者对所观察的目标对象黑盒操作:无相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

  1. 当一个对象的改变需要通知其他对象,并且不希望将对象之间的耦合度过高时,可以考虑使用观察者模式。
  2. 当某个对象的状态改变需要引起一系列相关对象的更新时,不需要知道这些对象是谁,不需知道具体有多少对象有待改变,可以使用观察者模式。
  3. 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

注意事项

  1. 注意观察者和被观察者的关联方式:可以通过接口或抽象类定义观察者接口,使得被观察者只与接口进行交互,而不依赖于具体的观察者实现类。
  2. 避免循环依赖:观察者和被观察者之间应该避免出现循环依赖的情况,否则可能导致无限循环的通知。
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,可采用异步方式进行通知。

实际应用

  1. 网络订阅服务:订阅者可以订阅感兴趣的内容,当内容更新时,订阅者会收到通知。
  2. 消息中间件:多个消息消费者可以同时监听一个消息主题,当主题发布消息时,所有消费者都会接收到通知并处理消息。
  3. GUI界面组件:GUI界面中的事件监听机制就是一种观察者模式的实现。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

相关文章:

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

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

Kernel Exception导致手机重启案例分析

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

C++入门篇5---模板

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

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 实验结果 论文地址&#xff1a;L2CS-Net: Fine-Grained Gaze Estimation…...

kenernetes/k8s笔试面试

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

我们真的是在做数据治理吗

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

聊聊汽车电子的话题

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

ThinkPHP6企业OA办公系统

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

PPS Tester测量原理和实施方法

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

浅谈新电改背景下电网企业综合能源服务商业模式研究及发展方向

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

SpringBoot + Docker 实现一次构建到处运行~

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

clang-format格式化代码

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

品牌宣传与媒体传播是声誉管理的主要方式之一

企业声誉是现如今影响品牌信任度、客户忠诚度的重要因素&#xff0c;也被视为企业的一种无形资&#xff0c;更影响着企业未来的发展。因此&#xff0c;企业声誉管理也日渐成为企业管理的重要课题之一&#xff0c;尤其在品牌营销管理领域。 什么是声誉管理&#xff1f;声誉管理有…...

2023年8月7日-8月13日,(上午熟悉公司代码,周一到周五晚上优先工作所急视频教程,其他业余时间进行ue视频教程,为独立游戏做准备)

按照规划&#xff0c;上午熟悉公司源码&#xff0c;下午进行filament和ue渲染&#xff0c;晚上写工作代码。回家后泛读pbrt或者其他书籍催眠。 业余学习ue的各种视频教程&#xff0c;为独立游戏做准备&#xff08;公司也实行末位淘汰&#xff0c;给自己留条后路&#xff09;。累…...

Vue3 第二节 Vue3的响应式

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

通过easyui实现动态控制表格字段显示、导出表格数据

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

JWT入门,jwt可以解密吗?

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

36.利用解fgoalattain 有约束多元变量多目标规划问题求解(matlab程序)

1.简述 多目标规划的一种求解方法是加权系数法&#xff0c;即为每一个目标赋值一个权系数&#xff0c;把多目标模型转化为一个单目标模型。MATLAB的fgoalattain()函数可以用于求解多目标规划。 基本语法 fgoalattain()函数的用法&#xff1a; x fgoalattain(fun,x0,goal,weig…...

EPPlus 读取和生成Excel

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

Java wait() notify() join()用法讲解

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

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...