3.7设计模式——Observer 观察者模式(行为型)

news/2024/5/15 17:12:16

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。

结构

  • Subject(目标)知道它的观察者,可以有任意多个观察者观察同一个目标,提供注册和删除观察者对象的接口。
  • Observer(观察者)为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
  • ConcreteSubject(具体目标)将有关状态存入个ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知。
  • ConcreteObserver(具体观察者)维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口,以使自身状态与目标的状态保持一致。

适用性

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在独立的对象中以使他们可以各自独立地改变和复用。
  • 当一个对象的改变需要同时改变其他对象,而不知道具体有多少个对象有待改变时。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象时谁,既不希望这些对象时紧耦合的。

代码示例

import java.util.ArrayList;
import java.util.List;// 观察者接口
interface Observer {void update();
}// 目标类
class Subject {private List<Observer> observers = new ArrayList<>();// 注册观察者public void registerObserver(Observer observer) {observers.add(observer);}// 删除观察者public void removeObserver(Observer observer) {observers.remove(observer);}// 当状态发生改变时通知观察者public void notifyObservers() {for (Observer observer : observers) {observer.update();}}
}// 具体目标类
class ConcreteSubject extends Subject {private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyObservers(); // 通知观察者状态改变}
}// 具体观察者类
class ConcreteObserver implements Observer {private ConcreteSubject subject;public ConcreteObserver(ConcreteSubject subject) {this.subject = subject;this.subject.registerObserver(this); // 注册观察者}@Overridepublic void update() {System.out.println("Observer updated, new state: " + subject.getState());}
}// 测试
public class ObserverPatternExample {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer1 = new ConcreteObserver(subject);ConcreteObserver observer2 = new ConcreteObserver(subject);subject.setState(10);subject.setState(20);}
}
  • 在这个示例中,将创建一个名为Subject的目标类和一个名为Observer的观察者接口,然后实现具体目标类ConcreteSubject和具体观察者类ConcreteObserver。具体目标类将实现注册和删除观察者对象的接口,并在状态发生改变时通知观察者。具体观察者类将实现更新接口,以使自身状态与目标的状态保持一致。
  • ConcreteSubject维护了一个观察者列表,并在状态发生改变时通知观察者。具体观察者类ConcreteObserver实现了更新接口,并在状态发生改变时更新自身状态。在测试中,创建了一个具体目标对象和两个具体观察者对象,并通过改变具体目标的状态来观察具体观察者的更新。

http://www.mrgr.cn/p/47537126

相关文章

Docker安装MySQL 5.7

1. 创建数据存储目录 先创建3个目录,创建MySQL容器时会挂载容器的卷。 mkdir log mkdir data mkdir conf2. Docker仓库查看MySQL3. 拉取镜像 docker pull mysql:5.74.创建MySQL配置文件 [client] default-character-set=utf8mb4[mysql] default-character-set=utf8mb4[mysqld]…

1-ICEM入门练习:正方体网格划分(六面体网格)

1. 前言 采用简单几何结构进行网格划分,主要目的是熟悉ICEM操作流程及网格划分思路,参考B站博主视频进行自己练习。基本操作:鼠标中键--平移、ctrl+鼠标左键--旋转、鼠标右键上下滑动--放大缩小2. 几何结构 采用spceclaim建模20mm20mm20mm正方体几何,无需定义边界,保存文件…

【C++ STL序列容器】list 双向链表

文章目录 【 1. 基本原理 】【 2. list 的创建 】2.1 创建1个空的 list2.2 创建一个包含 n 个元素的 list&#xff08;默认值&#xff09;2.3 创建一个包含 n 个元素的 list&#xff08;赋初值&#xff09;2.4 通过1个 list 初始化另一个 list2.5 拷贝其他类型容器的指定元素创…

uniapp分包,以及通过uni-simple-router进行分包

先说一下uniapp的直接分包方式&#xff0c;很简单&#xff1a; 配置分包信息 打开manifest.json源码视图&#xff0c;添加 “optimization”:{“subPackages”:true} 开启分包优化 我们在根目录下创建一个pagesA文件夹&#xff0c;用来放置需要分包的页面 然后配置路由 运行到…

Chrome您的连接不是私密连接解决办法(转)

原文:https://www.cnblogs.com/taoni/p/15860559.html 您的连接不是私密连接 攻击者可能会试图从 x.x.x.x 窃取您的信息(例如:密码、通讯内容或信用卡信息)。了解详情 NET::ERR_CERT_INVALID 将您访问的部分网页的网址、有限的系统信息以及部分网页内容发送给 Google,以帮…

2024数学建模时间汇总与竞赛攻略

目录 2024数学建模汇总&#xff08;时间、报名费、获奖率、竞赛级别、是否可跨校&#xff09; 中国高校大数据挑战赛 “华数杯”国际大学生数学建模竞赛 美国大学生数学建模竞赛&#xff08;美赛&#xff09; 数学中国&#xff08;认证杯&#xff09;数学建模网络挑战赛 …

《最新出炉》系列入门篇-Python+Playwright自动化测试-41-录制视频

1.简介 上一篇讲解和分享了录制自动生成脚本,索性连带录制视频也一股脑的在这里就讲解和分享了。今天我们将学习如何使用Playwright和Python来录制浏览器操作的视频,以便在需要时进行回放和分析。 2.录制视频语法 录制视频介绍官方API的文档地址:https://playwright.dev/pyt…

upload-labs挑战笔记

Pass-01 直接上传php木马,发现前端报错关掉JS,再次进行上传右键获取地址获取shellPass-02 在服务器端对数据包的MIME进行检查,只让Content-Type为image/jpeg | image/png | image/gif的文件通过。由此可知,它只对Content-Type做了判断,并没有对文件进行判断,因此我们可以…

JAVA实现easyExcel动态生成excel

添加pom依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version> </dependency><!--工具类--> <dependency><groupId>cn.hutool</groupId><…

WEB攻防-ASP安全-ASP后门植入连接

windows2003环境搭建&#xff0c;可参考上一篇WEB攻防-ASP安全-MDB下载-CSDN博客 将aspcms解压到C:\inetpub\wwwroot,创建网站并赋予internet来宾用户权限 配置启用父路径和主页指向 上一篇文章提到&#xff0c;数据库文件后缀为asp、asa会被执行解析&#xff0c;所以当进行访…

C# 批量删除Excel中的重复行

当从不同来源导入Excel数据时,可能存在重复的记录。为了确保数据的准确性,通常需要删除这些重复的行。手动查找并删除可能会非常耗费时间,而通过编程脚本则可以实现在短时间内处理大量数据。本文将提供一个使用C# 快速查找并删除Excel重复项的免费解决方案。以下是实现步骤:…

通过ModbusRS485转Profinet网关搭建汇川变频器与PLC的协议转换通道

在本次案例中,我们的主要控制对象是汇川的变频器。为了实现这一目的,客户现场选用了西门子的PLC,然而变频器为Modbus协议,两者无法完成直接通讯,所以选择通过ModbusRS485转Profinet网关模块来实现对变频器数据进行监控。具体设备配置如下:我们采用了汇川变频器,并通过耐…

Python绘制3D曲面图

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 探索Python中绘制3D曲面图的艺术 在数据可视化的世界中&#xff0c;3D曲面图是一种强大的工…

Media Session API

Media Session API 控制媒体播放和自定义媒体通知<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><ti…

diskMirror-backEnd-spring-boot | diskMirror 后端服务器 SpringBoot 版本!

diskMirror-backEnd-spring-boot diskMirror 后端服务器的 SpringBoot 版本&#xff0c;此版本中拓展了 DiskMirrorBackEnd&#xff0c;是一个完全的SpringBoot项目&#xff01; 目录 文章目录 diskMirror-backEnd-spring-boot目录我如何部署与配置docker 方式部署 diskMirro…

几种unhook手法的学习

文章首发阿里云先知社区:https://xz.aliyun.com/t/14310 了解过免杀的都知道,杀软会对敏感 api 进行 hook 操作,而我们通常有两种方式进行解决,syscall 和 unhook,而我们在 syscall 的时候有时候会导致堆栈不完整,在杀软看来是一些异常的行为,比如下图可以看到 RIP 指针…

openGauss MOT样例TPC-C基准

MOT样例TPC-C基准 TPC-C简介 TPC-C基准是衡量联机事务处理(OLTP)系统性能的行业标准基准。它基于一个复杂的数据库和许多不同的事务类型。这些事务类型在此基准上执行。TPC-C基准测试既不依赖硬件,也不依赖软件,因此可以在每个测试平台上运行。基准模型的官方概述,见tpc.o…

openGauss MOT资源利用率

MOT资源利用率 在4路96核512GB RAM的x86服务器上测试的资源利用率如下所示。MOT能够高效持续消耗几乎所有可用的CPU资源。例如,192核390万tpmC的CPU利用率几乎达到100%。tmpC:每分钟完成的TPC-C事务数以橙色条柱和左侧的Y轴 tpmC 表示。 CPU利用率(%):CPU利用率由蓝色线条…

openGauss MOT纵向扩容架构

MOT纵向扩容架构 纵向扩容即为同一台机器添加额外的核以增加算力。纵向扩容是传统上为单对控制器和多核的机器增加算力的常见形式。纵向扩容架构受限于控制器的可扩展性。 技术要求 MOT旨在实现以下目标:线性扩容:MOT提供事务性存储引擎,利用单个NUMA架构服务器的所有核,以…

Vim学习笔记01~04

第01章&#xff1a; 遁入空门&#xff0c;模式当道 1.什么是vim Vim是一个高效的文本编辑工具&#xff0c;并且可以在编程开发过程中发挥越来越重要的作用。 事实上&#xff0c;有不少编程高手使用他们来进行代码的开发&#xff0c;并且对此赞不绝口。 2.本系列目的 但是让…