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

笨蛋学设计模式行为型模式-观察者模式【14】

行为型模式-观察者模式

    • 8.1观察者模式:arrow_up::arrow_up::arrow_up:
      • 8.1.1概念
      • 8.1.2场景
      • 8.1.3优势 / 劣势
      • 8.1.4观察者模式可分为
        • 观察者的基本结构:
      • 8.1.5观察者模式
      • 8.1.6实战
        • 8.1.6.1题目描述
        • 8.1.6.2输入描述
        • 8.1.6.3输出描述
        • 8.1.6.4代码
      • 8.1.7总结

8.1观察者模式⬆️⬆️⬆️

8.1.1概念

​ 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,会通知所有依赖它的观察者对象,使它们都能够得到通知并且被自动更新

8.1.2场景

​ 在我们生活中,用户可以在音乐播放平台关注多个歌手,而当有歌手发布新的歌曲时,可以将歌曲发布到音乐播放平台,而平台会将新的歌曲详细信息发送给关注该歌手的用户。而此时歌手就相当于是观察者模式的主题对象,每个关注的用户则是观察者模式中的观察者对象,通过该模式,用户可以很及时的听到歌手的新歌曲,而歌手也可以很轻松的通知用户新歌曲的发布。

8.1.3优势 / 劣势

  • 灵活性:提供了灵活的观察者注册机制,可以随时添加或删除观察者,使得系统更加灵活和可扩展
  • 自动更新:当被观察者的状态发生改变时,所有依赖它的观察者都会自动收到通知并更新,提高了系统的自动化程度

  • 性能影响:当被观察者的状态发生改变时,所有观察者都会收到通知并且进行相应的通知,可能导致大量的通知和计算,影响系统性能
  • 通知竞态条件:若多个线程同时修改被观察者的状态,可能会产生竞态条件,导致某些观察者未能及时收到通知或收到错误的通知

8.1.4观察者模式可分为

  • 主题Subject:就是被观察的对象,可以维护一组观察者,当主题本身发生改变时就会通知观察者
  • 观察者Observer:观察主题的对象,当"被观察"的主题发生变化时,观察者就会得到通知并执行相应的处理

观察者的基本结构:
  • 主题Subject:一般会定义成一个接口,提供方法用于注册、删除、通知观察者,通常也包含一个状态,当状态发生改变时,通知所有的观察者
  • 观察者Observer:观察者也需要实现一个接口,包含一个更新方法,在接收主题通知时执行对应的操作
  • 具体主题ConcreteSubject:主题的具体实现,维护一个观察者列表,包含了观察者的注册、删除、通知方法
  • 具体观察者ConcreteObserver:观察者接口的具体实现,每个具体

8.1.5观察者模式

package com.technologystatck.designpattern.mode.observer;import java.util.ArrayList;
import java.util.List;public class Observers {public static void main(String[] args) {//创建具体主题对象ConcreteSubject concreteSubject = new ConcreteSubject();//创建具体观察者对象Observer concreteObserverA = new ConcreteObserver();Observer concreteObserverB = new ConcreteObserver();//注册观察者concreteSubject.registerObserver(concreteObserverA);concreteSubject.registerObserver(concreteObserverB);//调用主题方法concreteSubject.setState("有新的观察者注册");}
}//主题接口(主题)
interface Subject{//注册观察者void registerObserver(Observer observer);//移除观察者void removeObserver(Observer observer);//通知观察者void notifyObserver();
}//观察者接口(观察者)
interface Observer{//更新方法void update(String message);
}//具体主题实现
class ConcreteSubject implements Subject{//观察者列表private List<Observer> observers = new ArrayList<>();//状态private String state;//注册观察者方法(注册)@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}//移除观察者方法(移除)@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}//通知观察者方法(通知)//遍历观察者列表,并通知每个观察者更新状态@Overridepublic void notifyObserver() {for (Observer observer : observers) {observer.update(state);}}//更新状态public void setState(String state) {this.state = state;notifyObserver();}
}
//具体观察者实现
class ConcreteObserver implements Observer{//更新方法@Overridepublic void update(String message) {System.out.println(message);}
}

8.1.6实战

8.1.6.1题目描述

小明所在的学校有一个时钟(主题),每到整点时,它就会通知所有的学生(观察者)当前的时间,请你使用观察者模式实现这个时钟通知系统。

注意点:时间从 0 开始,并每隔一个小时更新一次。

8.1.6.2输入描述

输入的第一行是一个整数 N(1 ≤ N ≤ 20),表示学生的数量。

接下来的 N 行,每行包含一个字符串,表示学生的姓名。

最后一行是一个整数,表示时钟更新的次数。

8.1.6.3输出描述

对于每一次时钟更新,输出每个学生的姓名和当前的时间。

8.1.6.4代码
package com.technologystatck.designpattern.mode.observer;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 读取学⽣数量int N = scanner.nextInt();// 创建时钟Clock clock = new Clock();// 注册学⽣观察者for (int i = 0; i < N; i++) {String studentName = scanner.next();clock.registerObserver(new Student(studentName));}// 读取时钟更新次数int updates = scanner.nextInt();// 模拟时钟每隔⼀个⼩时更新⼀次for (int i = 0; i < updates; i++) {clock.tick();}}
}// 观察者接⼝
interface Observer {void update(int hour);
}
// 主题接⼝
interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}
// 具体主题实现
class Clock implements Subject {private List<Observer> observers = new ArrayList<>();private int hour = 0;@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(hour);}}public void tick() {hour = (hour + 1) % 24; // 模拟时间的推移notifyObservers();}
}
// 具体观察者实现
class Student implements Observer {private String name;public Student(String name) {this.name = name;}@Overridepublic void update(int hour) {System.out.println(name + " " + hour);}
}

8.1.7总结

  • 优点:可以灵活的增加 / 删除观察者对象,而不影响其他相关对象的功能
  • 总结:定义一对多的依赖关系,让多个观察者对象同时监听某一主题对象的状态变化,实现自动更新
  • 场景:适用于一个对象的状态变化会影响到其他对象,并且希望这些对象在状态变化时能够自动更新的情况

相关文章:

笨蛋学设计模式行为型模式-观察者模式【14】

行为型模式-观察者模式 8.1观察者模式:arrow_up::arrow_up::arrow_up:8.1.1概念8.1.2场景8.1.3优势 / 劣势8.1.4观察者模式可分为观察者的基本结构&#xff1a; 8.1.5观察者模式8.1.6实战8.1.6.1题目描述8.1.6.2输入描述8.1.6.3输出描述8.1.6.4代码 8.1.7总结 8.1观察者模式⬆️…...

上海智慧岛大数据云计算中心项目正式封顶!

上海智慧岛大数据云计算中心封顶仪式现场 1月15日&#xff0c;云端股份在上海智慧岛大数据云计算中心举行封顶仪式。云之端网络&#xff08;江苏&#xff09;股份有限公司&#xff08;以下称“云端股份”&#xff09;总经理贡伟力先生&#xff0c;常务副总张靖先生等公司成员&…...

靶场实战(19):OSCP备考之VulnHub HA WORDY

交流技术可以关注公众号 OneMoreThink 或后台添加微信&#xff0c;欢迎提出宝贵建议。 0、总结 0.1、攻击思路 资产发现 主机发现服务发现漏洞发现&#xff08;获取权限&#xff09; 80端口/HTTP服务 组件漏洞URL漏洞&#xff1a;RFI、FileUpload提升权限 www-data用户 sudosui…...

大模型学习与实践笔记(九)

一、LMDeply方式部署 使用 LMDeploy 以本地对话方式部署 InternLM-Chat-7B 模型&#xff0c;生成 300 字的小故事 2.api 方式部署 运行 结果&#xff1a; 显存占用&#xff1a; 二、报错与解决方案 在使用命令&#xff0c;对lmdeploy 进行源码安装是时&#xff0c;报错 1.源…...

fpga目前就业形势咋样?

FPGA今年各厂给本科生的薪资大概是15-30K&#xff0c;研究生是20-40K&#xff0c;平均薪资在25k左右&#xff0c; 当然具体薪资还要看去哪个公司&#xff0c;哪个城市&#xff0c;以及个人的学校、专业、能力水平、及包括面试时的表现&#xff0c;运气等&#xff0c;这些都会导…...

Linux7 安装 Oracle 19C RAC 详细图文教程

实战篇&#xff1a;Linux7 安装 Oracle 19C RAC 详细图文教程 本文是按照&#xff1a;https://www.modb.pro/db/154424的思路进行编写 一、安装前规划 安装RAC前&#xff0c;当然要先做好规划。具体包含以下几方面&#xff1a; 节点主机版本主机名实例名Grid/Oracle版本Publi…...

【SpringBoot】SpringBoot 项目初始化方法

github 搜索 springboot 模板 github 搜索 springboot 模板&#xff0c;拉取现成代码。 SpringBoot 官方的模板生成器 SpringBoot 官方的模板生成器&#xff08;https://start.spring.io/&#xff09; 在 IDEA 开发工具中生成 这里我修改成阿里的镜像主要是要使用 Java8。 …...

34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)

二分查找到目标值然后左右找到坐标 问题在于&#xff1a;找左右坐标的时候时间复杂度不是O(logN) class Solution {public int[] searchRange(int[] nums, int target) {int[] ans {-1, -1};if (nums.length 0) return ans;int l 0, r nums.length;while (l < r) {int…...

Mysql深度分页优化的一个实践

问题简述: 最近在工作中遇到了大数据量的查询场景, 日产100w左右明细, 会查询近90天内的数据, 总数据量约1亿, 业务要求支持分页查询与导出. 无论是分页或导出都涉及到深度分页查询, mysql通过limit/offset实现的深度分页查询会存在全表扫描的问题, 比如offset1000w, limit10…...

【JavaEE进阶】 SpringBoot配置⽂件

文章目录 &#x1f340;配置⽂件的作⽤&#x1f334;SpringBoot配置⽂件&#x1f38b;配置⽂件的格式&#x1f384;properties配置⽂件&#x1f6a9;properties基本语法&#x1f6a9;读取配置⽂件&#x1f6a9;properties的缺点 &#x1f333;yml配置⽂件yml基本语法&#x1f6…...

excel 常用函数

求和函数&#xff1a; SUM&#xff1a; 将单个值、单元格引用或区域相加。 案例&#xff1a;SUM(A1:A5) &#xff08;结果&#xff1a;A1到A5单元格的值求和&#xff09; SUMIF&#xff1a; 对选中范围内符合指定条件的值求和。 案例&#xff1a;SUMIF(B1:B5, ">50&qu…...

【React基础】– JSX语法

文章目录 认识JSX为什么React选择了JSXJSX的使用 React事件绑定this的绑定问题事件参数传递 React条件渲染React列表渲染列表中的key JSX的本质createElement源码Babel官网查看直接编写jsx代码 虚拟DOM的创建过程jsx – 虚拟DOM – 真实DOM声明式编程 阶段案例练习 认识JSX ◼ …...

SpringBoot 项目中后端实现跨域的5种方式!!!

文章目录 SpringBoot 项目中后端实现跨域的5种方式&#xff01;&#xff01;&#xff01;一、为什么会出现跨域问题二、什么是跨域三、非同源限制四、Java后端 实现 CORS 跨域请求的方式1、返回新的 CorsFilter(全局跨域)2、重写 WebMvcConfigurer(全局跨域)3、使用注解 (局部跨…...

Vue3前端开发,provide和enject的基础练习,跨层级传递数据

Vue3前端开发,provide和enject的基础练习,跨层级传递数据&#xff01; 声明:provide虽然可以跨层级传递&#xff0c;但是依旧是需要由上向下的方向传递。根传子的方向。 <script setup> import {onMounted, ref} from vue import Base from ./components/Base.vue impor…...

Python 循环结构值while循环

while循环是一种常用的循环结构&#xff0c;它会在满足特定条件的情况下重复执行一段代码块。 基本语法&#xff1a; while condition:# 循环体代码while循环的执行过程如下&#xff1a; 首先&#xff0c;判断循环条件condition&#xff08;布尔表达式&#xff09;是否为真。…...

MSSQL-识别扩展extended event(扩展事件)中的时间单位

经常使用sqlserver extended event(扩展事件)&#xff0c;但是总是忘记扩展事件使用的时间单位&#xff0c;不确定它们是 秒、毫秒、还是微秒&#xff1f; 以下下代码能够从 相关DMV中提取description字段内容来识别时间单位&#xff1a; SELECT [p].[name] [package_name],[o…...

vue3中l和vue2中v-model不同点

vue2比较让人诟病的一点就是提供了两种双向绑定&#xff1a;v-model和.sync&#xff0c; 在vue3中&#xff0c;去掉了.sync修饰符&#xff0c;只需要使用v-model进行双向绑定即可。 为了让v-model更好的针对多个属性进行双向绑定&#xff08;vue2中自定义组件中v-model只能使用…...

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标&#xff0c;尤其在今天这个时代&#xff0c;性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件&#xff0c;如网银系统、在线购物商城等&#xff0c;更是必须保证其高效稳定的性能。在这种背景下&#xff0c;优化…...

基于springboot+vue的社区团购系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…...

three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera</title><script src"ThreeJS/three.js"></script><script src&qu…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...