【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)

文章目录

    • 定义
    • 结构
    • Demo | 代码
      • Subject目标类
      • Observer抽象观察者
      • 观察者1 | CPU监听器
      • 观察者2 | 内存监听器
      • 客户端 | Client
    • 优点
      • 适合场景

定义

所谓观察者模式就是你是被观察的那个对象,你爸爸妈妈就是观察者,一天24h盯着你,一旦你不听话,他们要你听话,你的状态发生变化以后,他们接收到你的状态发生了改变。

image-20240704145502974

结构

如下图,服务器就作为被观察者,三个传感器就是观察者。这是一种抽象的表达方式!

image-20240704145601787

image-20240704150528837

  • Subject被观察的目标
  • Observer观察者抽象类
  • 具体观察者实现类
  • Client客户端

Demo | 代码

Subject目标类

我们需要一个Subject目标类,内部含有观察者对象的集合,在必要的时候触发事件。

  • Subject被观察的目标
  • Observer观察者抽象类
  • 具体观察者实现类
  • Client客户端

/*** 这个Server类就是服务类,作为Subject,别观察的目标!* @author linghu* @date 2024/7/4 11:50*/
public class Server {private List<Observer> observers= new ArrayList<Observer>();private int cpu;private int memory;public Server() {}//变更服务器状态public void changeState(int cpu,int memory){this.cpu=cpu;this.memory=memory;System.out.println("CPU:" + cpu + "%,内存占用:" + memory + "%");//通知所有观察者对象,使它们能够自动更新自己notifyAllObservers();}public Server(int cpu, int memory) {this.cpu = cpu;this.memory = memory;}public int getCpu() {return cpu;}public void setCpu(int cpu) {this.cpu = cpu;}public int getMemory() {return memory;}public void setMemory(int memory) {this.memory = memory;}public void addObserver(Observer observer){observers.add(observer);}public void notifyAllObservers(){for (Observer observer :observers) {observer.update();}}}

Observer抽象观察者

这个抽象主要是封装了目标对象和观察者要做的事情。

/*** @author linghu* @date 2024/7/4 12:02*/
public abstract class Observer {protected Server subject;//服务类,目标对象public abstract void update();//观察者要做的事情
}

观察者1 | CPU监听器

/*** @author linghu* @date 2024/7/4 12:04* CPU监听器*/
public class CpuObserver extends Observer{//传入目标类subjectpublic CpuObserver(Server subject) {//初始化的时候完成数据双向绑定工作this.subject=subject;this.subject.addObserver(this);}@Overridepublic void update() {//监听CPU的运行状况,负载超过80%就发出警报if(subject.getCpu() >= 80){System.out.println("警报:CPU当前" + subject.getCpu()+ "%即将满载,请 速查明原因");}}
}

观察者2 | 内存监听器

/*** @author linghu* @date 2024/7/4 12:46* 内存监听器*/
public class MemoryObserver extends Observer{public MemoryObserver(Server subject) {this.subject=subject;this.subject.addObserver(this);}@Overridepublic void update() {if(subject.getMemory() >= 80){System.out.println("警报:服务器内存已经占用超过" + subject.getMemory()+ "%即将满载,请 速查明原因");}}
}

客户端 | Client

/*** 观察者模式:让多个观察者对象同时监听某一个主题对象。* 这个主题对象在状态发生变化时,会通知所有观察者对象,* 使它们能够自动更新自己。* @author linghu* @date 2024/7/4 12:49* 客户端*/
public class Client {public static void main(String[] args) throws InterruptedException {Server subject = new Server();//完成两个观察者和一个目标类的绑定//引入新的观察者,这里可以利用反射,动态加载~new CpuObserver(subject);new MemoryObserver(subject);//==============================while (true){int cpu=new Random().nextInt(100);int memory=new Random().nextInt(100);//调用具体的业务~subject.changeState(cpu,memory);Thread.sleep(5000);//5s}}
}

优点

  • 开闭原则。 你⽆需修改发布者代码就能引⼊新的订阅者类 (如果是发布者接⼝则可轻松引⼊发布者类)。

  • 你可以在运⾏时建⽴对象之间的联系。

适合场景

  • 所有的发布订阅模式
  • 构建事件监听机制,比如按下触发click事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/39934.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【BUUCTF-PWN】7-[第五空间2019 决赛]PWN5

参考&#xff1a;BUU pwn [第五空间2019 决赛]PWN5 //格式化字符串漏洞 - Nemuzuki - 博客园 (cnblogs.com) 格式化字符串漏洞原理详解_printf 任意内存读取-CSDN博客 32位小端排序&#xff0c;有栈溢出保护 运行效果&#xff1a; 查看main函数 存在格式化字符串漏洞 输…

SQL二次注入原理分析

二次注入在测试的时候比较少见&#xff0c;或者说很难被测出来&#xff0c;因为测的时候首先要去找注入的位置&#xff0c;其次是去判断第一次执行的SQL语句&#xff0c;然后还要去判断第二次进行调用的 SQL 语句。而关键问题就出在第二次的调用上面。 下面以一个常用过滤方法…

macos下搭建minikube dashboard的启动

背景 最近在复习一下k8s环境相关的知识&#xff0c;需要在自己电脑上搭建一个minikube的环境供自己使用。但是因为docker的镜像仓库最近被墙了&#xff0c;因此在执行minikube dashboard的时候&#xff0c;拉不到相应的镜像&#xff0c;就导致页面看不到相应的一些信息因此本文…

【PYG】dataloader和densedataloader

DenseDataLoader 是专门用于处理稠密图数据的&#xff0c;而 DataLoader 通常用于处理稀疏图数据。两者的主要区别在于它们的输入数据格式和处理方式。DenseDataLoader 适合处理固定大小的邻接矩阵和节点特征矩阵的数据&#xff0c;而 DataLoader 更加灵活&#xff0c;可以处理…

flask中解决图片不显示的问题(很细微的点)

我在编写flask项目的时候&#xff0c;在编写html的时候&#xff0c;发现不管我的图片路径如何变化&#xff0c;其就是显示不出来。如下图我框中的地方。 我尝试过使用浏览器打开&#xff0c;是可以的。 一旦运行这个flask项目&#xff0c;就无法显示了。 我查阅资料后。发现…

简易版async/await

参考&#xff1a;https://juejin.cn/post/7007031572238958629?searchId20240704101813568E9B5B1013C881A239#heading-15 总结一下async/await的知识点 1、 await只能在async函数中使用&#xff0c;不然会报错 2、 async函数返回的是一个Promise对象&#xff0c;有无值看有…

泛微开发修炼之旅--29用计划任务定时发送邮件提醒

文章链接&#xff1a;29用计划任务定时发送邮件提醒

[单master节点k8s部署]17.监控系统构建(二)Prometheus安装

prometheus server安装 创建sa账号&#xff0c;对prometheus server进行授权。因为Prometheus是安装在pod里面&#xff0c;以pod的形式去运行的&#xff0c;因此需要创建sa&#xff0c;并对他做rbac授权。 apiVersion: v1 kind: ServiceAccount metadata:name: monitornamesp…

k8s-第九节-命名空间

命名空间 如果一个集群中部署了多个应用&#xff0c;所有应用都在一起&#xff0c;就不太好管理&#xff0c;也可以导致名字冲突等。 我们可以使用 namespace 把应用划分到不同的命名空间&#xff0c;跟代码里的 namespace 是一个概念&#xff0c;只是为了划分空间。 # 创建命…

LeetCode热题100刷题4:76. 最小覆盖子串、239. 滑动窗口最大值、53. 最大子数组和、56. 合并区间

76. 最小覆盖子串 滑动窗口解决字串问题。 labuladong的算法小抄中关于滑动窗口的算法总结&#xff1a; class Solution { public:string minWindow(string s, string t) {unordered_map<char,int> need,window;for(char c : t) {need[c];}int left 0, right 0;int …

2.8亿东亚五国建筑数据分享

数据是GIS的血液&#xff01; 我们现在为你分享东亚5国的2.8亿条建筑轮廓数据&#xff0c;该数据包括中国、日本、朝鲜、韩国和蒙古5个东亚国家完整、高质量的建筑物轮廓数据&#xff0c;你可以在文末查看领取方法。 数据介绍 虽然开源的全球的建筑数据已经有微软的建筑数据…

elementUI中table组件固定列时会渲染两次模板内容问题

今天在使用elementUI的table组件时&#xff0c;由于业务需要固定表格的前几项列&#xff0c;然后获取表格对象时发现竟然有两个对象。 查阅资料发现&#xff0c;elementUI的固定列的实现原理是将两个表格拼装而成&#xff0c;因此获取的对象也是两个。对于需要使用对象的方法的…

vxe-table的序号一样

使用vxe-table的时候&#xff0c;有的时候会出现序号相同的现象&#xff0c;这种现象一般出现在我们后面自己添加的行中&#xff0c;就像这种 此时的这三个序号是相同的&#xff0c;我来说一下原因&#xff0c;这是在添加新的一行的时候&#xff0c;有的时候数据很多&#xff0…

Mac 运行 Windows 软件,Parallels Desktop 19和 CrossOver 24全面对比

Parallels Desktop 和 CrossOver 都是能满足你「在 Mac 上运行 Windows 软件」需求的工具。可能很多人都已经知道 Parallels Desktop 是「虚拟机」&#xff0c;但 CrossOver 其实并不是「虚拟机」。这两款软件有相同的作用&#xff0c;但由于实现原理的不同&#xff0c;两者也有…

系统提示我未定义与 ‘double‘ 类型的输入参数相对应的函数 ‘finverse‘,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Kubernetes 部署简单的应用

Kubernetes 部署简单的应用 Kubernetes 是一个强大的容器编排平台&#xff0c;它可以帮助我们自动化应用程序的部署、扩展和管理。在本期文章中&#xff0c;我们将学习如何使用 Kubernetes 部署一个简单的应用程序。 1. 环境准备 确保你已经安装了 Kubernetes 集群&#xff…

【python模块】argparse

文章目录 argparse模块介绍基本用法add_argument() argparse模块介绍 argparse 模块是 Python 标准库中的一个用于编写用户友好的命令行接口&#xff08;CLI&#xff09;的模块。它允许程序定义它所需要的命令行参数&#xff0c;然后 argparse 会自动从 sys.argv 解析出那些参…

TCP粘包解决方法

一. 产生原因及解决方法 产生原因&#xff1a;TCP是面向连接、基于字节流的协议&#xff0c;其无边界标记。当服务端处理速度比不其接收速度时&#xff0c;就很容易产生粘包现象。 解决方法&#xff1a;目前主要有两种解决方法&#xff0c;一个是在内容中添加分割标识&#xf…

人脸识别考勤系统

人脸识别考勤系统是一种利用生物识别技术进行自动身份验证的现代解决方案&#xff0c;它通过分析和比对人脸特征来进行员工的出勤记录。这种系统不仅提升了工作效率&#xff0c;还大大减少了人为错误和欺诈行为的可能性。 一、工作原理 人脸识别考勤系统的核心在于其生物识别…

深入剖析Python中的Pandas库:通过实战案例全方位解读数据清洗与预处理艺术

引言 随着大数据时代的到来&#xff0c;数据的质量直接影响到最终分析结果的可靠性和有效性。在这个背景下&#xff0c;Python凭借其灵活强大且易于上手的特点&#xff0c;在全球范围内被广泛应用于数据科学领域。而在Python的数据处理生态中&#xff0c;Pandas库无疑是最耀眼…