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

观察者模式(Observer)

观察着模式是一种行为设计模式,可以用来定义对象间的一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

Observer is a behavior design pattern that can be used to define one to many dependencies between objects,
so that whenever an object's state changes, its related dependent objects are notified and automatically updated.
Observer pattern is also called Publish/Subscribe mode, Model/View mode, Source/Listener mode or Dependents mode.  

结构设计

观察者模式包含如下角色:
Subject: 目标,提供注册和删除观察者对象的接口。会向观察者对象发送值得关注的事件。
ConcreteSubject: 具体目标,实现注册和删除观察者对象的接口。当目标的状态发生改变时,目标会遍历观察者列表并调用每个观察者对象的通知方法。
Observer: 观察者,为那些在目标发生改变时,需获得通知的对象定义了一个更新接口。在绝大多数情况下,该接口仅包含一个update方法。该方法可以拥有多个参数,使目标能在状态更新时传递详细信息。
ConcreteObserver: 具体观察者,维护一个指向ConcreteSubject的引用。实现Observer的更新接口,已使自身状态与目标状态保持一致。
观察者模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下观察者模式的实现。

// 1、观察者,定义了一个更新接口,用于目标发生改变时,传递详细信息
public class Observer {public void update() {System.out.println("I am an observer instance");}
}
// 2、具体观察者,实现观察者的更新接口,使自身状态与目标状态保持一致
public class ConcreteObserver extends Observer {public void update() {super.update();doSomething();}private void doSomething() {System.out.println("I am a concrete observer instance");}
}
// 3、目标,提供注册和删除观察者对象的接口,会向观察者对象发送值得关注的事件  
public abstract class Subject {private List<Observer> observerList = new ArrayList<>();public void attach(Observer observer) {observerList.add(observer);}public void detach(Observer observer) {observerList.remove(observer);}public void notifyObserver() {if (observerList == null || observerList.size() == 0) {return;}observerList.forEach(Observer::update);}public abstract void doSomething();
}
// 4、具体目标,实现目标的接口,指定通知观察者的具体时机
public class ConcreteSubject extends Subject {public void doSomething() {notifyObserver();}
}
// 5、客户端
public class ObserverClient {public void test() {Observer observer1 = new ConcreteObserver();Observer observer2 = new ConcreteObserver();Subject subject = new ConcreteSubject();subject.attach(observer1);subject.attach(observer2);subject.doSomething();subject.detach(observer2);subject.doSomething();}
}

适用场景

在以下情况下可以考虑使用观察者模式:
(1) 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
(2) 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可使用观察者模式,以降低对象之间的耦合度。
(3) 一个对象必须通知其他对象,而并不知道这些对象是谁。
(4) 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

优缺点

观察者模式有以下优点:
(1) 松耦合。在观察目标和观察者之间建立一个抽象的耦合。
(2) 符合开闭原则。无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
(3) 支持广播通信。
(4) 可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
但是该模式也存在以下缺点:
(1) 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2) 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
(3) 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

参考

《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/observer.html 观察者模式
https://refactoringguru.cn/design-patterns/observer 观察者模式
https://www.runoob.com/design-pattern/observer-pattern.html 观察者模式
https://www.cnblogs.com/adamjwh/p/10913660.html 简说设计模式——观察者模式
https://blog.csdn.net/ShuSheng0007/article/details/125122173 秒懂设计模式之观察者模式

相关文章:

观察者模式(Observer)

观察着模式是一种行为设计模式&#xff0c;可以用来定义对象间的一对多依赖关系&#xff0c;使得每当一个对象状态发生改变时&#xff0c;其相关依赖对象皆得到通知并被自动更新。 观察者模式又叫做发布-订阅&#xff08;Publish/Subscribe&#xff09;模式、模型-视图&#xf…...

20天学会rust(二)rust的基础语法篇

在第一节&#xff08;20天学rust&#xff08;一&#xff09;和rust say hi&#xff09;我们配置好了rust的环境&#xff0c;并且运行了一个简单的demo——practice-01&#xff0c;接下来我们将从示例入手&#xff0c;学习rust的基础语法。 首先来看下项目结构&#xff1a; 项目…...

Stephen Wolfram:嵌入的概念

The Concept of Embeddings 嵌入的概念 Neural nets—at least as they’re currently set up—are fundamentally based on numbers. So if we’re going to to use them to work on something like text we’ll need a way to represent our text with numbers. And certain…...

springboot,swagger多个mapper包,多个controller加载问题

启动类添加MapperScan({"xxx.xxx.xxx.mapper","xxx.xxx.xxx.mapper"}) swagger配置类添加 Bean public Docket api01() {return new Docket(DocumentationType.SWAGGER_2)//.enable(swagger_is_enabl).apiInfo(new ApiInfoBuilder().title("你的title…...

湖大CG满分教程:作业训练四编程题20. 回文串(暴力×动态规划算法√)

问题描述 “回文串”是一个正读和反读都一样的字符串&#xff0c;比如“level”或者“noon”等等就是回文串。给你一个字符串&#xff0c;问最少在字符串尾添加多少字符&#xff0c;可以使得字符串变为回文串。 输入格式 有多组测试数据。 每组测试数据第一行是一个正整数N…...

使用toad库进行机器学习评分卡全流程

1 加载数据 导入模块 import pandas as pd from sklearn.metrics import roc_auc_score,roc_curve,auc from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression import numpy as np import math import xgboost as xgb …...

Python数据容器——列表(list)

数据容器入门 Python中的数据容器&#xff1a; 一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素 每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 数据容器根据特点的不同&#xff0c;如&#xff1a;是否支持重复元…...

Linux CEF(Chromium Embedded Framework)源码下载编译详细记录

Linux CEF&#xff08;Chromium Embedded Framework&#xff09;源码下载编译 背景 由于CEF默认的二进制分发包不支持音视频播放&#xff0c;需要自行编译源码&#xff0c;将ffmpeg开关打开才能支持。这里介绍的是Linux平台下的CEF源码下载编译过程。 前置条件 下载的过程非…...

Adaptive AUTOSAR—— Communication Management 3.1

9 Communication Management 9.1 What is Communication Management? 通信管理是自适应平台架构中的一个功能集群。 作为一个功能集群,通信管理向应用程序提供了一个C++ API,实现了面向服务的通信。服务是一个由应用程序提供的功能单元,可以在运行时被另一个应用程序动态…...

VMnet0 桥接设置

VMnet0 一定要设置为你的硬件物理网卡&#xff0c;不能设置自动&#xff0c;不然后&#xff0c;网线一断&#xff0c;就再也连不上了。必须重启电脑才能连上&#xff0c;这个问题找了很久才找到。 下面有个hyper-V虚拟网卡&#xff0c;如果选自动的话&#xff0c;物理网卡一掉…...

Sublime Text 4 Build 4151 4152 发布及注册方法

Sublime Text 是一个商业代码编辑器。它原生支持许多编程语言和标记语言&#xff0c;用户可以通过插件来扩展它的功能&#xff0c;这些插件通常是由社区建立的&#xff0c;并以自由软件许可证的形式维护。为了方便插件&#xff0c;Sublime Text 有一个 Python API。 Sublime T…...

第八篇: K8S Prometheus Operator实现Ceph集群企业微信机器人告警

Prometheus Operator实现Ceph集群企业微信告警 实现方案 我们的k8s集群与ceph集群是部署在不同的服务器上&#xff0c;因此实现方案如下&#xff1a; (1) ceph集群开启mgr内置的exporter服务&#xff0c;用于获取ceph集群的metrics (2) k8s集群通过 Service Endponit Ser…...

软件单元测试

单元测试目的和意义 对于非正式的软件&#xff08;其特点是功能比较少&#xff0c;后续也不有新特性加入&#xff0c;不用负责维护&#xff09;&#xff0c;我们可以使用debug单步执行&#xff0c;内存修改&#xff0c;检查对应的观测点是否符合要求来进行单元测试&#xff0c…...

Redis | 集群模式

Redis | 集群模式 随着互联网应用规模的不断扩大&#xff0c;单一节点的数据库性能已经无法满足大规模应用的需求。为了提高数据库的性能和可扩展性&#xff0c;分布式数据库成为了解决方案之一。Redis 作为一个高性能的内存数据库&#xff0c;自然也有了自己的分布式部署方式…...

8.3day04git+数据结构

文章目录 git版本控制学习高性能的单机管理主机的心跳服务算法题 git版本控制学习 一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;帮助开发团队维护代码 作用&#xff1a;记录代码内容&#xff0c;切换代码版本&#xff0c;多人开发时高效合并代码内容 安装g…...

04-5_Qt 5.9 C++开发指南_QComboBox和QPlainTextEdit

文章目录 1. 实例功能概述2. 源码2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. 实例功能概述 QComboBox 是下拉列表框组件类&#xff0c;它提供一个下拉列表供用户选择&#xff0c;也可以直接当作一个QLineEdit 用作输入。OComboBox 除了显示可见下拉列表外&#xff0c;每个…...

Sqlserver_Oracle_Mysql_Postgresql不同关系型数据库之主从延迟的理解和实验

关系型数据库主从节点的延迟是否和隔离级别有关联&#xff0c;个人认为两者没有直接关系&#xff0c;主从延迟在关系型数据库中一般和这两个时间有关&#xff1a;事务日志从主节点传输到从节点的时间事务日志在从节点的应用时间 事务日志从主节点传输到从节点的时间&#xff0…...

Clickhouse学习系列——一条SQL完成gourp by分组与不分组数值计算

笔者在近一两年接触了Clickhouse数据库&#xff0c;在项目中也进行了一些实践&#xff0c;但一直都没有一些技术文章的沉淀&#xff0c;近期打算做个系列&#xff0c;通过一些具体的场景将Clickhouse的用法进行沉淀和分享&#xff0c;供大家参考。 首先我们假设一个Clickhouse数…...

做好“关键基础设施提供商”角色,亚马逊云科技加快生成式AI落地

一场关于生产力的革命已在酝酿之中。全球管理咨询公司麦肯锡在最近的报告《生成式人工智能的经济潜力&#xff1a;下一波生产力浪潮》中指出&#xff0c;生成式AI每年可能为全球经济增加2.6万亿到4.4万亿美元的价值。在几天前的亚马逊云科技纽约峰会中&#xff0c;「生成式AI」…...

如何使用 ChatGPT 规划家居装修

你正在计划家庭装修项目&#xff0c;但不确定从哪里开始&#xff1f;ChatGPT 随时为你提供帮助。从集思广益的设计理念到估算成本&#xff0c;ChatGPT 可以简化你的家居装修规划流程。在本文中&#xff0c;我们将讨论如何使用 ChatGPT 有效地规划家居装修&#xff0c;以便你的项…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...