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

小谈设计模式(15)—观察者模式

小谈设计模式(15)—观察者模式

  • 专栏介绍
    • 专栏地址
    • 专栏介绍
  • 观察者模式
    • 核心思想
    • 主要角色
      • Subject(被观察者)
      • ConcreteSubject(具体被观察者)
      • Observer(观察者)
      • ConcreteObserver(具体观察者)
    • Java程序实现
      • 输出结果
      • 程序分析
    • 优缺点分析
      • 优点
        • 解耦性
        • 可扩展性
        • 一对多关系
      • 缺点
        • 观察者过多
        • 循环依赖
        • 更新顺序问题
    • 总结

专栏介绍

专栏地址

link

专栏介绍

主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
在这里插入图片描述

观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新自己。

在这里插入图片描述

核心思想

将观察者和被观察者之间的依赖关系解耦,使其彼此之间可以独立变化。被观察者只需要知道观察者实现了某个接口,而不需要知道具体的观察者类,同样,观察者只需要知道被观察者实现了某个接口,而不需要知道具体的被观察者类。
在这里插入图片描述

主要角色

Subject(被观察者)

定义了被观察者的接口,包含注册观察者、移除观察者和通知观察者的方法。

ConcreteSubject(具体被观察者)

实现了被观察者接口,维护观察者列表,并在状态发生改变时通知观察者。

Observer(观察者)

定义了观察者的接口,包含更新方法,用于接收被观察者的通知。

ConcreteObserver(具体观察者)

实现了观察者接口,具体实现更新方法,在接收到被观察者的通知时进行相应的处理。
在这里插入图片描述

Java程序实现

// 定义观察者接口
interface Observer {void update(String message);
}// 定义被观察者接口
interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers(String message);
}// 具体观察者类
class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " received message: " + message);}
}// 具体被观察者类
class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String message) {for (Observer observer : observers) {observer.update(message);}}
}// 测试代码
public class ObserverPatternExample {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();Observer observer1 = new ConcreteObserver("Observer 1");Observer observer2 = new ConcreteObserver("Observer 2");subject.registerObserver(observer1);subject.registerObserver(observer2);subject.notifyObservers("Hello, observers!");subject.removeObserver(observer2);subject.notifyObservers("Observer 2 has been removed!");}
}

输出结果

Observer 1 received message: Hello, observers!
Observer 2 received message: Hello, observers!
Observer 1 received message: Observer 2 has been removed!

程序分析

在上述示例中,我们定义了一个观察者接口(Observer)和一个被观察者接口(Subject)。具体观察者类(ConcreteObserver)和具体被观察者类(ConcreteSubject)实现了对应的接口。
在这里插入图片描述

优缺点分析

优点

解耦性

观察者模式可以将观察者和被观察者之间的依赖关系解耦,使得它们可以独立变化。当被观察者发生变化时,只需要通知观察者即可,而不需要知道具体有哪些观察者存在。

可扩展性

观察者模式可以很方便地增加新的观察者,而不需要修改被观察者的代码。这符合开闭原则,使得系统更加灵活和可扩展。

一对多关系

观察者模式可以实现一对多的依赖关系,一个被观察者可以有多个观察者。这样可以方便地实现事件监听、消息订阅等功能。

在这里插入图片描述

缺点

观察者过多

当观察者过多时,被观察者通知观察者的时间可能会较长,影响系统的性能。

循环依赖

如果观察者和被观察者之间存在循环依赖关系,可能会导致系统出现问题,如死锁等。

更新顺序问题

观察者模式中观察者的更新顺序是不确定的,可能会导致观察者之间的依赖关系出现问题。

总结

可以提高系统的灵活性和可扩展性。但同时也需要注意观察者过多、循环依赖和更新顺序等问题,以确保系统的稳定性和性能。在使用观察者模式时,需要根据具体的场景和需求进行权衡和设计。

相关文章:

小谈设计模式(15)—观察者模式

小谈设计模式&#xff08;15&#xff09;—观察者模式 专栏介绍专栏地址专栏介绍 观察者模式核心思想主要角色Subject&#xff08;被观察者&#xff09;ConcreteSubject&#xff08;具体被观察者&#xff09;Observer&#xff08;观察者&#xff09;ConcreteObserver&#xff0…...

简单工厂模式 创建型模式(非GoF经典设计模式)

简单工厂模式是属于创建型模式&#xff0c;也因为工厂中的方法一般设置为静态&#xff0c;又叫做静态工厂方法&#xff08;Static Factory Method&#xff09;模式&#xff0c;但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工…...

PE文件之导入表

1. 导入表 2. 显示导入表信息的例子 ; 作用: 将RVA地址转成FOA即文件偏移 ; 参数: _pFileHdr 指向读到内存中文件的基址指针 ; _dwRVA 目标RVA地址 ; 返回: 目标RVA转成文件偏移的值 RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORDmov esi, _pFil…...

二、码制及其转换

原码 根据我们所学可知&#xff0c;数字电路的逻辑电路是通过输出0和1来表示二进制数的&#xff0c;那么这个二进制数的正负又该怎么表示呢&#xff1f; 答案是在这个二进制数的最高位作为符号位来表示正负性&#xff0c;用0正数&#xff0c;用1表示负数&#xff0c;在这种表达…...

在pycharm中出现下载软件包失败的解决方法

一. 一般情况下我们会选择在设置中下载软件包,过程如下. 1. 直接点击左上角的文件, 再点击设置, 再点击项目, 在右边选择python解释器,点击号,输入要下载的软件包, 在下面的一系列的包中选择相对应的包,点击安装就可以了,有的时候我们下载的是最新的版本,如果要下载固定的版本…...

10.0 探索API调试事件原理

本章笔者将通过Windows平台下自带的调试API接口实现对特定进程的动态转存功能&#xff0c;首先简单介绍一下关于调试事件的相关信息&#xff0c;调试事件的建立需要依赖于DEBUG_EVENT这个特有的数据结构&#xff0c;该结构用于向调试器报告调试事件。当一个程序发生异常事件或者…...

文心一言 VS 讯飞星火 VS chatgpt (104)-- 算法导论10.1 2题

二、用go语言&#xff0c;说明如何在一个数组 A[1…n]中实现两个栈&#xff0c;使得当两个栈的元素个数之和不为 n 时&#xff0c;两者都不会发生上溢。要求 PUSH 和 POP 操作的运行时间为 O(1)。 文心一言&#xff1a; 在这个问题中&#xff0c;我们要在一个数组 A[1…n] 中…...

检测防火墙是否开启、判断程序是否加入防火墙白名单(附源码)

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…...

vtk 动画入门 1 代码

实现效果如图&#xff1a; #include <vtkAutoInit.h> //VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //VTK_MODULE_INIT(vtkRenderingFreeType); #in…...

【VR】【unity】如何在VR中实现远程投屏功能?

【背景】 目前主流的VD应用,用于娱乐很棒,但是用于工作还是无法效率地操作键鼠。用虚拟键盘工作则显然是不现实的。为了让自己的头显能够起到小面积代替多显示屏的作用,自己动手开发投屏VR应用。 【思路】 先实现C#的投屏应用。研究如何将C#投屏应用用Unity 3D项目转写。…...

OpenGl材质

在现实世界里,每个物体会对光产生不同的反应。比如,钢制物体看起来通常会比陶土花瓶更闪闪发光,一个木头箱子也不会与一个钢制箱子反射同样程度的光。有些物体反射光的时候不会有太多的散射(Scatter),因而产生较小的高光点,而有些物体则会散射很多,产生一个有着更大半径的…...

背包问题

目录 开端 01背包问题 AcWing 01背包问题 Luogu P2925干草出售 Luogu P1048采药 完全背包问题 AcWing 完全背包问题 Luogu P1853投资的最大效益 多重背包问题 AcWing 多重背包问题 I AcWing 多重背包问题 II Luogu P1776宝物筛选 混合背包问题 AcWing 混合背包问题…...

JavaSE | 初始Java(十一) | 抽象类和抽象接口

抽象类概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c; 如果 一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类 在 Java 中&#xff0c;一个…...

产品经理如何科学的进行需求调研?

导语&#xff1a;作为产品经理&#xff0c;需求调研是开展工作的重要环节之一。科学、有效地进行需求调研不仅可以帮助产品经理更好地了解用户需求&#xff0c;还能指导产品设计和功能开发&#xff0c;提升产品的竞争力。本文将介绍几种科学的方法和技巧&#xff0c;帮助产品经…...

AI智能问答系统源码/AI绘画商业系统/支持GPT联网提问/支持Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…...

玩具玩偶配送经营商城小程序的作用是什么?

玩具玩偶是小孩子们喜欢的产品&#xff0c;其市场需求度很高&#xff0c;以前玩具店里总是不缺乏客户&#xff0c;但现在随着人们生活品牌提升及消费形式改变&#xff0c;无论玩具厂商还是门店经销商都面对着不少痛点&#xff1a; 如拓客引流难、线上销售经营难、营销难、分销…...

latex表格内容换行

问题描述&#xff1a; 在用latex表格中编写公式时&#xff0c;可能出现公式太长&#xff0c;表格中后面的内容不能在文档中呈现&#xff0c;如下图1&#xff0c;故要进行行内内容的换行&#xff0c;使内容呈现完全而传统的\换行后,换行内容会顶格&#xff0c;如图2。 解决方…...

2023 牛客国庆day4 【10.2训练补题】

目录 B-Basic Gcd Problem&#xff08;素数筛快速幂&#xff09; H-Harder Gcd Problem&#xff08;素数&#xff09; B-Basic Gcd Problem&#xff08;素数筛快速幂&#xff09; 打表找规律发现答案为 (n质因子数目)^c #include<bits/stdc.h> using namespace std;…...

android的USB开发时 mUsbManager.getDeviceList()获取都为空

类提供的主要方法有&#xff1a; getDeviceList() 获得设备列表&#xff0c;返回的是一个HashMap.;hasPermission(UsbDevice device) 判断你的应用程序是否有接入此USB设备的权限&#xff0c;如果有则返回真&#xff0c;否则返回false.openDevice(UsbDevice device) 打开USB设…...

SpringCloud Alibaba - Seata 部署 TC 服务,并集成微服务

目录 一、Seata 架构 1.1、Seata 架构重要角色 1.2、部署 TC 服务 1.2.1、前言 1.2.2、下载 seata-server 包&#xff0c;解压 1.2.3、修改配置 1.2.4、在 nacos 中添加配置 1.2.5、创建数据库表 1.2.6、启动 TC 服务 1.3、微服务集成 Seata 1.3.1、引入依赖 1.3.2、…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...