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

news2024/11/20 21:33:34

文章目录

    • 定义
    • 结构
    • 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{

    //传入目标类subject
    public CpuObserver(Server subject) {
        //初始化的时候完成数据双向绑定工作
        this.subject=subject;
        this.subject.addObserver(this);
    }

    @Override
    public 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);
    }

    @Override
    public 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.coloradmin.cn/o/1895925.html

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

相关文章

前端引用vue/element/echarts资源等引用方法Blob下载HTML

前端引用下载vue/element/echarts资源等引用方法 功能需求 需求是在HTML页面中集成Vue.js、Element Plus&#xff08;Element UI的Vue 3版本&#xff09;、ECharts等前端资源&#xff0c;使用Blob下载HTML。 解决方案概述 直接访问线上CDN地址&#xff1a;简单直接&#xff0c…

实训学习错误总结2

1、 "timestamp": "2024-07-04T08:43:07.15400:00", "status": 405, "error": "Method Not Allowed", "path": "/wuzi/insert" 简单的来说就是使用的方法与注释不匹配。 规定的是&#xff1a;Get&a…

图DFS遍历

DFS遍历图 伪代码 俩函数。 判断图有几个连通分支&#xff1f;就是图的遍历&#xff0c;dfs完了就给他 #include <iostream> #include <cstdlib> #include <bits/stdc.h> #include <vector> using namespace std; const int N102; int n,m,temp1,te…

从开源小白到新晋 committer:主动尝试,心无旁骛,收获满满!

又一位清华同学加入&#xff01; 2024 年 6 月 12 日&#xff0c;经 Apache IoTDB 社区投票&#xff0c;杨蔡胤成为 Apache IoTDB committer。之前从未参加过开源社区贡献的他&#xff0c;为什么选择了 IoTDB&#xff0c;又为什么能够坚持到现在&#xff0c;有什么样的收获与成…

NASA——quarius(水瓶座) L3 网格化 1 度年土壤湿度,第 5 版

Aquarius L3 Gridded 1-Degree Annual Soil Moisture V005 水瓶座 L3 网格化 1 度年土壤湿度&#xff0c;第 5 版 简介 该数据集包含美国国家航空航天局&#xff08;NASA&#xff09;科学应用卫星&#xff08;SAC-D&#xff09;上的宝瓶座被动微波辐射计得出的第 3 级网格化…

【Axure高保真原型】中继器表格——移入显示详情卡片案例

今天和大家分享中继器表格——移入显示详情卡片的原型模板&#xff0c;鼠标移入员工号或姓名会弹出员工卡片&#xff0c;可以查看更详细的信息。这个表格是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;只需要维护中继器表格里的信息&#xff0c;即可自动生成交互效…

数据结构之二叉树概念

数据结构之二叉树 二叉树简介分类普通二叉树平衡二叉树满二叉树二叉搜索树&#xff08;二叉排序树、二叉查找树&#xff09;&#xff0c;平衡二叉树红黑树 B树类型B树&#xff08;B-树、B_树&#xff09;B树B*树 二叉树 简介 二叉树(Binary Tree) &#xff1a;是一种非常重要…

SQL MINUS 运算符:查找数据集之间的差异

在 SQL 中&#xff0c;MINUS 运算符在查询中起着至关重要的作用&#xff0c;它允许开发人员识别和检索存在于一个数据集中但不存在于另一个数据集中的记录。本文探讨了 SQL 中 MINUS 运算符的功能、用法和实际应用&#xff0c;强调了它在数据分析和操作任务中的重要性。 理解 …

2G 3G 4G常用知识点

名词解释 LTE网络、WCDMA网络、2G、3G 4G 区别及联系? 2G (第二代移动通信技术) 2G是最早的数字移动电话标准&#xff0c;主要支持语音通话和短信服务。代表性技术有GSM (Global System for Mobile Communications) 和CDMA (Code Division Multiple Access)。 3G (第三代移动…

location匹配和rewrite重定向

目录 location 匹配 location匹配的分类和优先级 优先级细分 实际网站中的使用规则 1.用精确匹配来实现网站的首页 访问网站的首页 &#xff08; /&#xff09; 2.用正则匹配来实现静态请求的页面和图片 匹配静态页面 访问图片或者指定的后缀名 3.用一般匹配转发.php…

鸿蒙HarmonyOS深度探索课程

在这门课程中&#xff0c;我们将深入探索鸿蒙HarmonyOS平台的Java UI布局技术&#xff0c;结合新浪新闻、直聘App和华为商城等三个经典案例&#xff0c;从布局设计到实现细节&#xff0c;从交互体验到用户界面优化&#xff0c;逐步解析其UI布局的全面技术与设计思路。通过本课程…

Python | Leetcode Python题解之第216题组合总和III

题目&#xff1a; 题解&#xff1a; class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:"""回溯法&#xff0c;对于当前k和n, 枚举元素"""def backtracking(k: int, n: int, ans: List[int]):if k 0 or n <…

【python数据处理】— “2020-01-01 05:20:15“日期格式数据

文章目录 一、数据说明及目标二、实现方式1.提取date2.提取hour3.提取weekday4.提取month 一、数据说明及目标 数据说明 数据表有一列名为"datetime"表示时间数据&#xff0c;该列的数据格式是"2020-01-01 05:20:15"。 import pandas as pd datapd.read_e…

2.2.1 ROS2案例以及案例分析

1.案例需求 需求1&#xff1a;编写话题通信实现&#xff0c;发布方以某个频率发布一段文本&#xff0c;订阅方订阅消息&#xff0c;并输出在终端。 需求2&#xff1a;编写话题通信实现&#xff0c;发布方以某个频率发布自定义接口消息&#xff0c;订阅方订阅消息&#xff0c;并…

Java | Leetcode Java题解之第213题打家劫舍II

题目&#xff1a; 题解&#xff1a; class Solution {public int rob(int[] nums) {int length nums.length;if (length 1) {return nums[0];} else if (length 2) {return Math.max(nums[0], nums[1]);}return Math.max(robRange(nums, 0, length - 2), robRange(nums, 1,…

7/4 第六周 数据库的组合查询

今天开始确定需要报考系统架构师&#xff0c;后续早上就看架构师的书&#xff0c;等完成python的课程之后再去全力投入架构师。后续看视频的速度就需要快一些&#xff0c;不能理解就先跳过。特别是前端的一些内容就只看视频暂时不练习了。

自然语言处理学习(3)RNN 模型学习---NLP领域的第一个模型

一 基本定义 视频链接 1.小案例理解–语义理解 目的&#xff1a;输入一句话&#xff0c;机器需要理解这句话的语义 二. RNN模型分类 1. 按照输入输出分类 (1) N Vs N (2) N Vs 1 (3) 1 VsN (4) seq2seq 三 传统RNN模型 1. 内部结构分析 &#xff08;a) 总体外…

数据库第07讲章节测验期末复习题

一. 单选题 1【单选题】下面对于关系的叙述中,不正确的是_______。 A、关系中的每个属性是不可分解的B、在关系中元组的顺序是无关紧要的C、任意的一个二维表都是一个关系D、每一个关系只有一种记录类型 正确答案&#xff1a;C 2【单选题】关系模型的完整性约束不包括&#…

Ollama + Docker + AnythingLLM 搭建本地多用户AI知识库

整个过程需要准备三个工具&#xff1a; Ollama&#xff1a; 用于运行本地大模型的管理&#xff1a;llama3, qwen2等 Docker&#xff1a;用于运行AnythingLLM。 AnythingLLM&#xff1a;知识库运行平台&#xff0c;提供知识库构建及运行的功能。 Ollama, Docker 这二个安装不…

vue3 引入百度地图的三种方式

本次也是正好写了一个基于VUE3和百度地图的设计&#xff0c;但奈何第一次使用百度地图&#xff0c;在学习的途中遇到了很多问题&#xff0c;也发现网上的材料相对较少&#xff0c;因此做出了一些小总结&#xff0c;后续还会更新。 一、直接引入 直接在public中的index.html中进…