设计模式(行为型模式)观察者模式
目录
- 一、简介
- 二、观察者模式
- 2.1、事件接口及其实现
- 2.2、观察者接口及其实现
- 2.3、主题接口及其实现
- 2.4、使用
- 三、优点与缺点
一、简介
观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖者(观察者)都会自动收到通知并进行更新。
在观察者模式中,存在两类角色:
- 主题(Subject): 也称为被观察者或可观察对象,维护了一组观察者对象,并提供了添加、删除和通知观察者的方法。
- 观察者(Observer): 也称为订阅者,定义了一个更新接口或抽象类,用于接收主题的通知并进行相应的处理。
主题维护了一个观察者列表,当其内部状态发生变化时,会通知所有注册的观察者对象,使它们能够根据主题状态的变化进行相应的更新或处理。
观察者模式将主题和观察者解耦,使得主题和观察者之间的依赖关系变得松散,同时也提高了系统的灵活性和可扩展性。这种模式常用于订阅/发布系统、事件驱动系统以及需要一对多依赖关系的场景中。
二、观察者模式
下面是一个稍微复杂一些的观察者模式的示例,多个不同的观察者监听某个事件,并根据事件执行不同的操作(发送短信、发送邮件等):
2.1、事件接口及其实现
// 事件接口
public interface Event {String getEventData();
}// 具体事件类
public class ConcreteEvent implements Event {private String eventData;public ConcreteEvent(String data) {this.eventData = data;}@Overridepublic String getEventData() {return eventData;}
}
2.2、观察者接口及其实现
// 观察者接口
public interface Observer {void update(Event event);
}// 具体观察者 -- 邮件
public class EmailObserver implements Observer {@Overridepublic void update(Event event) {System.out.println("发送邮件: " + event.getEventData());}
}// 具体观察者 -- 短信
public class SMSObserver implements Observer {@Overridepublic void update(Event event) {System.out.println("发送短信: " + event.getEventData());}
}
2.3、主题接口及其实现
// 主题接口
public interface Subject {void attach(Observer observer);void detach(Observer observer);void notifyObservers(Event event);
}import java.util.ArrayList;
import java.util.List;// 具体主题
public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void attach(Observer observer) {observers.add(observer);}@Overridepublic void detach(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(Event event) {for (Observer observer : observers) {observer.update(event);}}
}
2.4、使用
public class ObserverPatternExample {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();Observer smsObserver = new SMSObserver();Observer emailObserver = new EmailObserver();subject.attach(smsObserver);subject.attach(emailObserver);Event event = new ConcreteEvent("你正在登录账户,查看Alian的博客");subject.notifyObservers(event);}
}
运行结果:
发送短信: 你正在登录账户,查看Alian的博客
发送邮件: 你正在登录账户,查看Alian的博客
三、优点与缺点
观察者模式具有以下优点和缺点:
优点
- 解耦和灵活性: 主题和观察者之间的关系是松散耦合的,主题无需知道观察者的细节,使得系统更加灵活,能够方便地扩展和维护。
- 一对多的依赖关系: 允许一个主题对象同时与多个观察者对象建立联系,当主题状态发生变化时,所有依赖于它的观察者都会得到通知。
- 支持广播通信: 观察者模式支持广播通信机制,主题对象发出的通知会被所有相关的观察者接收。
缺点
- 可能导致系统性能下降: 如果观察者过多或者操作复杂,通知所有观察者可能会影响性能。
- 可能导致循环依赖: 观察者和主题之间的循环依赖可能会导致系统问题,需要小心设计以避免这种情况。
- 可能引起内存泄漏: 如果观察者对象未被正确地移除,可能会导致内存泄漏问题。
总的来说,观察者模式是一种灵活、解耦的设计模式,能够实现对象间的一对多依赖关系。然而,在使用时需注意控制观察者数量、避免循环依赖和及时移除不需要的观察者,以确保系统的性能和稳定性。这个模式应用很广泛,比如springboot源码的事件发布机制。
相关文章:
设计模式(行为型模式)观察者模式
目录 一、简介二、观察者模式2.1、事件接口及其实现2.2、观察者接口及其实现2.3、主题接口及其实现2.4、使用 三、优点与缺点 一、简介 观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象…...

Windows 版Oracle 数据库(安装)详细过程
首先到官网上去下载oracle64位的安装程序 第一步:将两个datebase文件夹解压到同一目录中。 当下载完成后,它里面是两个文件夹 win64_11gR2_database_1of2, win64_11gR2_database_2of2,我们需要把其中的一个database文件夹整合在一起(复制一个database文件夹到另一…...

编程实例分享,计费系统一定要安装灯光控制吗?佳易王计时计费管理系统软件V18.0教程说明
编程实例分享,计费系统一定要安装灯光控制吗?佳易王计时计费管理系统软件V18.0教程说明 一、前言 以下教程以 佳易王计时计费软件V18.0为例说明 1、该软件既可以接灯控,也可以不接灯控,如果接灯控,则点击开始计时的时…...

【webpack】优化提升
webpack优化提升 安装webpack相关内容向下兼容游览器-babel/polyfill进一步优化babel/polyfill模块联邦-共享模块如何提升构建性能通用环境下1,webpack更新到最新版本2,将loader应用于最少数量的必要模块3,引导(每个额外的loader/…...

视频无损放大修复工具Topaz Video AI 新手入门教程
想要自学Topaz Video AI ?Topaz Video AI 如何使用?这里给大家带来了视频无损放大修复工具Topaz Video AI 新手入门教程,快来看看吧! 下载:Topaz Video AI for mac 导入您的文件 有两种方法可以将文件导入 Topaz Vid…...

《向量数据库指南》——Milvus Cloud 「部署」:简化部署一直在路上
“docker-compose 能部署分布式吗?”"单机部署为什么还依赖这么多组件?"“大家 Milvus Cloud 集群部署有没有实践过比较好的方案?” 作为一个开源数据库,是否能够进行快速部署,是所有工作的前提。在简化部署的道路上,社区从来没有停止过脚步。2023 年,社区推…...

使用x86架构+Nvidia消费显卡12G显存,搭建智能终端,将大模型本地化部署,说不定是未来方向,开源交互机器人设计
1,大模型本地部署 视频说明地址: https://www.bilibili.com/video/BV1BF4m1u769/ 【创新思考】(1):使用x86架构Nvidia消费显卡12G显存,搭建智能终端,将大模型本地化部署,语音交互机…...

关于RabbitMQ面试题汇总
什么是消息队列?消息队列有什么用? 消息队列是一种在应用程序之间传递消息的通信机制。它是一种典型的生产者-消费者模型,其中生产者负责生成消息并将其发送到队列中,而消费者则从队列中获取消息并进行处理。消息队列的主要目的是…...
GoogleTest 单元测试
假设我们有两个函数 complexFunction 和 helperFunction,其中 complexFunction 调用了 helperFunction。我们将编写测试 complexFunction 的单元测试,并在调用 helperFunction 的地方打桩。 // 复杂函数示例 int helperFunction(int x) {return x * 2; …...

Mac利用brew安装mysql并设置初始密码
前言 之前一直是在windows上开发后段程序,所以只在windows上装mysql。(我记得linux只需要适应yum之类的命令即可) 另外, linux的移步 linux安装mysql (详细步骤,初次初始化,sql小例子,可视化操作客户端推荐) 好家伙,我佛了,写完当天网上发…...
R语言入门笔记2.2
ifelse语句 结构:ifelse(条件,表达式1,表达式2) #满足条件,则进入表达式1,否则为表达式2 例1: > a1 > ifelse(a<0,"a小于0",ifelse(a0,0,"a大于0")) [1] "a大于0"a1 - 这行代码给变量a…...

一般系统的请求认证授权思路【gateway网关+jwt+redis+请求头httpheader】
gateway:网关,我们都知道网关的作用就是对系统的所有请求,网关都会进行拦截,然后做一些操作(例如:设置每个请求的请求头httpHeader,身份认证等等)此时一般会使用到网关过滤器&#x…...
c# 正则表达式 帮助类
public class RegexHelper { /// <summary> /// 验证输入字符串是否与模式字符串匹配,匹配返回true /// </summary> /// <param name"input">输入字符串</param> /// <param nam…...

告别mPDF迎来TCPDF和中文打印遇到的问题
mPDF是一个用PHP编写的开源PDF生成库。它最初由Claus Holler创建,于2004年发布。原来用开源软件打印中文没有问题,最近发现新的软件包中mPDF被TCPDF代替了,当然如果只用西文的PDF是没有发现问题,但要打印中文就有点抓瞎了如图1&am…...

mysql 多数据源
依赖 <dependencies><!--mysql连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--多数据源--><dependency><g…...

uniapp 使用renderjs引入echarts
效果图: 1.1renderjs引入echarts 组件zmui-echarts.vue: <template><view class"zmui-echarts" :prop"option" :change:prop"echarts.delay"></view> </template><script>export defaul…...

hr最讨厌这6种应届生简历❌
用求职方法,让你变成offer收割机,是我的责任❗ 简历写得好,面试少不了。最近很多应届生找龙猫帮看简历,我发现很多应届生是真不会写简历啊。 有的简历排版花里胡哨,有的自我评价千篇一律,有的实习经历太过…...

【Linux笔记】文件系统与软硬链接
一、文件系统概述 1.1、先来聊一聊“磁盘” 在讲解文件系统之前,我觉得有必要先聊一下“磁盘”,因为我觉得如果弄懂了磁盘的存储原理,大家可能更容易理解文件系统是怎么管理数据的,并且理解计算机是怎么将磁盘抽象到文件系统的。…...

vue3(笔记)
组合式Api setup-----相当于beforeCreate, create生命周期 reactive–定义状态 对象形式 响应式原理 toRefs— Pinia (只有state、getters和actions) 更加简洁的语法,完美支持Vue3的Composition api 和 对TypesCcript的完美支持...

Java面向对象 this
this 在Java中,this 是一个特殊的引用变量,它引用了当前对象实例。当在类的非静态方法或构造方法中使用时,this 关键字指代当前的对象实例。它经常用于区分对象的成员变量和局部变量,或者调用其他重载的方法。 以下是一些使用 t…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...