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

设计模式2 - 观察者模式

定义
观察者模式又叫发布订阅模式,它定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

组成
Subject(通知者/被观察者):指代的就是那个被观察者,通常由接口或者抽象类实现,常见方法有addObserver/deleteObserver方法用来增删观察者,notifyObservers状态改变时通知观察者
ConcreteSubject (具体通知者/被观察者):这个就是具体的被观察者类,实现上面的Subject接口
Observer (观察者):就是观察Subject的观察者,是个接口,只有1个update()方法,被观察者改变时会被调用,也就是说它可以通过这个方法来获取到被观察者的状态更新
ConcreteObserver (具体观察者类):实现上面的Observer接口

适用场景
当一个对象状态发生改变,会导致其他对象都发生改变

例子

(Subject.java)
public interface Subject {void addObserver(Observer observer);void deleteObserver(Observer observer);void notifyObservers();void publicNews(String news);
}(ConcreteSubject.java)
public class ConcreteSubject implements Subject {private ArrayList<Observer> observers;private String news;public ConcreteSubject() {observers = new ArrayList<>();}@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void deleteObserver(Observer observer) {int i = observers.indexOf(observer);if (i >= 0) {observers.remove(i);}}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(this, news);}}public void publicNews(String news) {this.news = news;notifyObservers();}
}(Observer.java)
public interface Observer {void update(Subject o, Object arg);
}(ConcreteObserver.java)
public class ConcreteObserver implements Observer{private Subject subject;public ConcreteObserver(Subject subject){this.subject = subject;this.subject.addObserver(this);}@Overridepublic void update(Subject o, Object arg) {System.out.println("收到的新闻: "+ arg);}
}(TestClient.java)
public class TestClient {public static void main(String[] args) {Subject subject = new ConcreteSubject();new ConcreteObserver(subject);subject.publicNews("今天我们的生活怎么样?");subject.publicNews("为什么有人骑在我们的脖子上?");}
}

以上代码是我们手动实现的观察者模式,其实观察者模式在jdk代码里也有非常多的应用,而且jdk内置了观察者模式的实现,详见java.util.Observable和java.util.Observer。以下是一些该模式的要点:

1、该模式定义了对象之间一对多的关系。
2、主题(被观察者)用一个共同的接口来更新观察者。
3、有多个观察者时,不可以依赖特定的通知顺序。
4、使用此模式时,你可以从被观察者处推(push)或拉(pull)数据,然后推的方式被认为是更合理的操作。
5、观察者和被观察者之间松耦合,被观察者不知道观察者的细节,只知道观察者实现了观察者接口。

相关文章:

设计模式2 - 观察者模式

定义&#xff1a; 观察者模式又叫发布订阅模式&#xff0c;它定义了对象之间的一对多依赖&#xff0c;这样一来&#xff0c;当一个对象改变状态时&#xff0c;它的所有依赖者都会收到通知并自动更新。 组成&#xff1a; Subject&#xff08;通知者/被观察者&#xff09;&#…...

ini配置文件

ini配置文件 ini文件是initialization file的缩写&#xff0c;即初始化文件&#xff0c;是widows系统配置文件所采用的存储格式。 文件扩展名: .ini ini配置文件的后缀名也不一定必须是.ini, 也可以是.cfg, .conf或者是.txt ini文件格式 ini配置文件由参数, 节, 注解组成 参…...

蓝桥杯备赛经验 pythonA组(非科班选手)

个人2022 CA组江苏省一等奖&#xff0c;决赛成绩不理想&#xff0c;没有拿到一二等奖&#xff0c;但是因为自己是非科班的学生&#xff0c;所以能拿到这样的成绩自己其实也应该知足了 题外话&#xff1a; 很多ACMer嘲笑蓝桥杯非常水&#xff0c;但是据我观察CA组决赛一等奖获奖…...

C++实现通讯录管理系统

通讯录是一个可以记录亲人、好友信息的工具&#xff0c;本博客借助黑马程序员的项目进行修改&#xff0c;利用C实现一个通讯录管理系统&#xff0c;旨在复习C的语法。 一、系统需求 系统需要实现的功能如下&#xff1a; 添加联系人∶向通讯录中添加新人&#xff0c;信息包括…...

开关电源Y电容放置的位置

Y电容&#xff0c;是我们工程师做开关电源设计时都要接触到的一个非常关键的元器件&#xff0c;它对EMI的贡献是相当的大的&#xff0c;但是它是一个较难把控的元器件&#xff0c;原理上并没有那么直观易懂&#xff0c;在EMI传播路径中需要联系到很多的寄生参数才能够去分析。 …...

二叉树的最小深度——递归法、迭代法

1题目给定一个二叉树&#xff0c;找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明&#xff1a;叶子节点是指没有子节点的节点。示例 1&#xff1a;输入&#xff1a;root [3,9,20,null,null,15,7]输出&#xff1a;2示例 2&#xff1a;输入&…...

Vue中常使用的三种刷新页面的方式

一、通过js原始方法刷新 缺点&#xff1a; 出现闪白 目录 一、通过js原始方法刷新 二、通过Vue自带的路由进行跳转 三、通过在APP页面进行demo进行刷新(推荐) 1.vue2写法 2. vue3.2写法 <template><div><div class"header"><button clic…...

【Shell】脚本

Shell脚本脚本格式第一个Shell脚本&#xff1a;hello.sh脚本常用执行方式1. bash或sh脚本的相对路径或绝对路径2. 输入脚本的绝对路径或相对路径3. 在脚本的路径前加上.或者source脚本格式 脚本以#!/bin/bash开头&#xff08;指定解析器&#xff09; #! 是一个约定的标记&…...

Mybatis的多表操作

1.Mybatis多表查询 1.1一对一查询 1.一对一查询的模型 用户表和订单表的关系为&#xff0c;一个用户有多个订单&#xff0c;一个订单只从属于一个用户 一对一查询的需求&#xff1a;查询一个订单&#xff0c;与此同时查询出该订单所属的用户2.创建Order和User实体public class…...

【JVM】字节码指令全解

文章目录 入门案例原始 java 代码编译后的字节码文件常量池载入运行时常量池方法字节码载入方法区main 线程开始运行,分配栈帧内存执行引擎开始执行字节码bipush 10istore_1ldc #3istore_2iload_1iload_2iaddistore_3getstatic #4iload_3invokevirtual #5return条件判断指令循…...

【精品】华为认证数通HCIA+HCIP题库分享(含答案解析)

嗨~大家好久不见&#xff0c;我是薄荷学姐&#xff0c;随着华为业务也全球领域的迅猛发展&#xff0c;越来越多人开始重视华为认证的重要性。今天给大家分享一下去年8月份的题库&#xff0c;基本都是一样&#xff0c;希望可以帮助到大家哈想要通过华为认证&#xff0c;除了进行…...

Qt cmake 资源文件的加载

Qt cmake 资源文件的加载概述qt_add_resourcesqt5_add_resourcesqt6_add_resources是否需要加载qrc文件需要加载qrc的情况不需要加载qrc的情况C 代码加载示例加载PNG加载CSS文件加载qrc文件Qt6相对于Qt5的一些变化Qt6和Qt5在加载资源文件方面的区别主要集中在两个方面&#xff…...

【链表OJ题(九)】环形链表延伸问题以及相关OJ题

环形链表OJ题 1. 环形链表 链接&#xff1a;141. 环形链表 描述&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&…...

【C++初阶】四、类和对象(下)

文章目录一、再谈构造函数构造函数体赋值初始化列表explicit关键字二、Static成员引入- 计算类中创建了多少个类对象概念特性静态成员函数的访问三、友元友元函数友元类四、内部类五、匿名对象六、拷贝对象时的一些编译器优化一、再谈构造函数 构造函数体赋值 在创建对象时&a…...

IDEA maven没有Import Maven projects automatically解决办法

去年装了个 IDEA2022版本 配置maven时我才发现是个大坑 他没有import Maven projects automatically配置项 当时看到我人都麻了 然后项目呢 用了依赖 这东西还不会自动下依赖 整的我那是相当难受 还在最后还是找到了解决办法 我们在配置文件上点击右键 然后鼠标选择如下图选项…...

Java实习生------MySQL10道面试题打卡

今日语录&#xff1a;“没有执行力&#xff0c;就没有竞争力 ”&#x1f339; 参考资料&#xff1a;图解MySQL、MySQL面试题 1、事务有哪些特性&#xff1f; 原子性&#xff1a; 一个事务中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#xff0c;不会出现…...

帆软报表设计器 数据集之数据库查询

当点击数据库查询时,调用TableDataTreePane的 public void actionPerformed(ActionEvent var1) {TableDataTreePane.this.dgEdit(this.getTableDataInstance().creatTableDataPane(), TableDataTreePane.this.createDsName(this.getNamePrefix()), false);} 然后调用TableDat…...

CSDN 第三十七期竞赛题解

很少有时间来玩玩题目&#xff0c;上一次因为环境极为嘈杂的原因在时间上没有进入前十&#xff0c;挺遗憾的。 在 CSDN 参加的第一次没出锅的比赛。 大概只有最后一题值得好好讲讲。 T1&#xff1a;幼稚班作业 幼稚园终于又有新的作业了。 老师安排同学用发给同学的4根木棒拼接…...

Vue实战【常用的Vue小魔法】

目录&#x1f31f;前言&#x1f31f;能让你首次加载更快的路由懒加载&#xff0c;怎么能忘&#xff1f;&#x1f31f;你是否还记得有一个叫Object.freeze的方法&#xff1f;&#x1f31f;异步组件那么强&#xff0c;你是不是没用过&#xff1f;&#x1f31f;你是不是还在comput…...

用C跑爬虫

爬虫自指定的URL地址开始下载网络资源&#xff0c;直到该地址和所有子地址的指定资源都下载完毕为止。 下面开始逐步分析爬虫的实现。 待下载集合与已下载集合 为了保存需要下载的URL&#xff0c;同时防止重复下载&#xff0c;我们需要分别用了两个集合来存放将要下载的URL和…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...