行为型-观察者模式(Observer)

观察者模式(Observer Pattern)是一种软件设计模式,主要用于在对象之间建立一对多的依赖关系,以便当一个对象的状态发生改变时,其所有依赖的对象都会得到通知并自动更新。观察者模式属于行为型模式。以下是关于观察者模式的主要知识点,按照清晰的结构进行归纳:

1. 基本概念

  • 定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它的所有依赖者(观察者)都会自动收到通知并更新。
  • 别名:有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式。

2. 特点

  • 松耦合:主题和观察者之间通过抽象接口进行交互,使得它们可以独立演化而不影响彼此。
  • 一对多关系:一个主题可以有多个观察者,并且它们之间没有直接联系。
  • 可扩展性:可以随时增加新的观察者或删除现有观察者。

3. 优点

  • 解耦合:将主题与具体观察者解耦,使得它们可以独立地变化和复用。
  • 扩展性:易于添加新的观察者以及定义新的事件类型。
  • 实时性:实现了实时更新机制,当主题状态改变时能够即刻通知相关观察者。

4. 缺点

  • 性能问题:过度使用可能导致性能问题和复杂度增加。
  • 触发链问题:如果观察者之间有依赖关系,那么通知链可能会导致不可预料的结果。

5. 角色

  • 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
  • 具体主题(Concrete Subject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
  • 抽象观察者(Observer):定义了一个更新接口,使得在得到主题的更改通知时更新自己。
  • 具体观察者(Concrete Observer):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。

6. 应用场景

  • 当一个对象的改变需要同时影响其他多个对象时。
  • 当系统中存在一些对象之间的联动行为,但又希望它们之间解耦合时。
  • 图形用户界面(GUI)的设计中,如按钮点击事件的处理。
  • 消息订阅与发布的场景,如新闻订阅、实时数据监控等。
  • 游戏中升级所触发的一系列动作

7. 实现方式

  • 使用自定义接口:主题和观察者都实现相应接口,在主题中维护一个观察者列表,并在状态改变时遍历通知所有观察者。

8.代码示例

1.定义观察者接口
public interface Observer {  void update(String message);  
}
2.定义被观察者(主题)接口
import java.util.ArrayList;  
import java.util.List;  public interface Subject {  void registerObserver(Observer observer);  void removeObserver(Observer observer);  void notifyObservers(String message);  
}
3.实现被观察者(主题)
public class ConcreteSubject implements Subject {  private List<Observer> observers;  private String state;  public ConcreteSubject() {  this.observers = new ArrayList<>();  }  @Override  public void registerObserver(Observer observer) {  observers.add(observer);  }  @Override  public void removeObserver(Observer observer) {  int index = observers.indexOf(observer);  if (index >= 0) {  observers.remove(index);  }  }  @Override  public void notifyObservers(String message) {  for (Observer observer : observers) {  observer.update(message);  }  }  // 模拟主题状态改变的方法  public void setState(String state) {  this.state = state;  notifyObservers("主题状态已更改为:" + state);  }  // 获取主题状态的方法(可选)  public String getState() {  return state;  }  
}
4.实现观察者
public class ConcreteObserver implements Observer {  private String name;  public ConcreteObserver(String name) {  this.name = name;  }  @Override  public void update(String message) {  System.out.println(name + " 收到通知:" + message);  }  
}
5.使用
public class ObserverPatternDemo {  public static void main(String[] args) {  ConcreteSubject subject = new ConcreteSubject();  Observer observer1 = new ConcreteObserver("观察者1");  Observer observer2 = new ConcreteObserver("观察者2");  subject.registerObserver(observer1);  subject.registerObserver(observer2);  subject.setState("新状态"); // 这会触发通知,并调用所有观察者的update方法  subject.removeObserver(observer1); // 移除一个观察者  subject.setState("另一个新状态"); // 这会再次触发通知,但只通知观察者2  }  
}

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

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

相关文章

lvgl手势事件判断为点击事件问题

lvgl手势事件判断为点击事件问题处理方法 1.打开文件lvgl\src\core\lv_indev.c 2. 修改函数 static void indev_proc_release(_lv_indev_proc_t * proc)2.1 由原来的 /*** Process the released state of LV_INDEV_TYPE_POINTER input devices* @param proc pointer to an …

学习笔记——交通安全分析05

目录 前言 当天学习笔记整理 交通行为、心理与安全 结束语 前言 #随着上一轮SPSS学习完成之后&#xff0c;本人又开始了新教材《交通安全分析》的学习 #整理过程不易&#xff0c;喜欢UP就点个免费的关注趴 #本期内容接上一期04笔记 当天学习笔记整理 交通行为、心理与…

关于Flutter doctor里两个警告的消除

在终端里输入 flutter doctor 是我们检查flutter是否配置好的方法。 在输出信息里常碰到两个警告 ! Warning: dart on your path resolves to /usr/local/Cellar/dart/2.18.6/libexec/bin/dart,which is not inside your current Flutter SDK checkout at /Users/dengpeng/fl…

三运放仪表放大器通过设置单个电阻器的值来调整增益

从公式 1 中可以看出&#xff0c;我们可以通过调整单个电阻器 R G的值来调整仪表放大器的差分增益。这很重要&#xff0c;因为与电路中的其他电阻器不同&#xff0c; RG的值不需要与任何其他电阻器匹配。 例如&#xff0c;如果我们尝试通过更改 R 5的值来设置增益&#xff0c;…

TGI模型- 同期群-评论文本

用户偏好分析 TGI 1.1 用户偏好分析介绍 要分析的目标&#xff0c;在目标群体中的均值 和 全部群体里的均值进行比较&#xff0c; 差的越多说明 目标群体偏好越明显 TGI&#xff08;Target Group Index&#xff0c;目标群体指数&#xff09;用于反映目标群体在特定研究范围内…

在自己的电脑上搭建我的世界Java版服务器

很多朋友&#xff0c;喜欢玩Minecraft&#xff0c;也希望搭建一个服务器&#xff0c;用于和小伙伴联机&#xff1b; 并且&#xff0c;拥有服务器后&#xff0c;即使所有玩家都下线&#xff0c;“世界”依旧在运行&#xff0c;玩家可以随时参与其中&#xff0c;说不定一上线&am…

有状态服务和无状态服务

有状态服务和无状态服务在不同的业务场景下有不同的应用&#xff0c;以下是一些常见的例子&#xff1a; 有状态服务的场景&#xff1a; 用户会话管理&#xff1a; 用户登录后&#xff0c;会话信息&#xff08;如用户ID、权限、购物车内容等&#xff09;需要在服务端保持状态。…

一种新的一维时间序列信号盲解卷积算法(以旋转机械故障诊断为例,MATLAB环境)

一种新的一维时间序列信号盲解卷积算法&#xff08;以旋转机械故障诊断为例&#xff0c;MATLAB环境&#xff09;&#xff0c;可作为深度学习信号前处理过程&#xff0c;水个SCI不是问题。 机械设备的状态信号中往往蕴含着大量的设备异常信息。如何从繁多的机械状态信号中提取足…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(五)质量设计方法与工具

第五节 质量设计方法与工具 1 任 务 分 解 法 1.1 概念 任务分解法&#xff0c;又称工作分解结构 (Work Breakdown Structure, 简 称 WBS) 。WBS 指以可交付成果为 导向&#xff0c;对项目团队为实现项目目标并完成规定的可交付成果而执行的工作所进行的层次分解。W…

程序员基本功之git的使用

阿里网盘-资料链接 文章目录 git分布式版本控制工具git的基本概念开发过程中的问题常见的版本控制工具git分布式版本控制工具特点git系统所定制的若干目标git的工作流程图 GIT的安装和常用命令**创建本地git仓库步骤****本地git仓库的使用**git log详解 git分布式版本控制工具…

SpringCloud跨服务远程调用

随着项目的使用者越来越多&#xff0c;项目承担的压力也会越来越大&#xff0c;为了让我们的项目能服务更多的使用者&#xff0c;我们不得不需要把我们的单体项目拆分成多个微服务&#xff0c;就比如把一个商城系统拆分成用户系统&#xff0c;商品系统&#xff0c;订单系统&…

MQTT TCP HTTP 协议对比

目录 1. 类型与用途 2. 通信模式与特性 3. 优缺点 4. 使用场景 MQTT、TCP和HTTP在类型、用途、通信模式、特性以及使用场景等方面存在显著的区别&#xff0c;以下是详细的阐述&#xff1a; 1. 类型与用途 MQTT&#xff1a;MQTT是一种消息传输协议&#xff0c;主要适用于物…

增加软件投入的重要性:提升自动化程度与用户界面设计的价值

一、引言 在许多项目中&#xff0c;硬件系统通常占据了大量预算&#xff0c;而对软件的投入相对较少。这种不平衡往往导致软件自动化程度低、操作不便、界面简陋&#xff0c;过多的人工干预不仅降低了工作效率&#xff0c;还影响了用户体验。特别是对于一些国家项目&#xff0…

matlab:数字信号处理过程(趋势+峰值+包络+滤波+FFT)仿真

数字信号处理 消除趋势找峰值求包络平滑fftclc;clear;close all; figure(1);clf; Fs = 200;%采样频率 T = 1/Fs; %采样周期 N = 300;

「C系列」C 结构体

文章目录 一、C 结构体1. 定义结构体2. 声明结构体变量3. 初始化结构体变量4. 访问结构体成员5. 结构体数组6. 结构体指针7. 结构体嵌套 二、C 如何使用结构体1. 定义结构体类型2. 声明结构体变量3. 初始化结构体变量4. 访问结构体成员5. 结构体指针6. 在函数中使用结构体7. 注…

docker run的复杂使用

sudo docker run -dit --namenmediacross1.x -v $HOME:$HOME -v /tmp/.X11-unix:/tmp/.X11-unix -v /dev/dri:/dev/dri --privileged --networkhost -e DISPLAYunix$DISPLAY -w $HOME nova:nmediacross1.x这个Docker命令相当复杂&#xff0c;包含了许多选项和参数&#xff0c;…

记录一次CTF图片拼图安装工具montage+gaps成功步骤以及踩坑全过程

安装图片拼接工具montage&#xff1a; 1.安装 使用pip install montage无法安装montage工具的师傅可以尝试下面的方法 #Debian apt-get install graphicsmagick-imagemagick-compat#Ubuntu apt-get install graphicsmagick-imagemagick-compat#Alpine apk add imagemagick6#…

安全相关的一些基础知识(持续更新)

目录 1. TRNG真随机数生成 2. 对称加密和非对称加密及其区别 3. Hash算法&#xff08;摘要算法&#xff09; 4. HTTPS、TLS、SSL、HTTP区别和关系 HTTPS的基本原理 5. PSS 1. TRNG真随机数生成 True Random Number Generator 在真随机数的生成里&#xff0c;把随机数的生…

编译rk3568 Android,rk3568_r-user和rk3568_r-userdebug的区别

在 Android 开发环境中,lunch 命令用于选择编译目标设备和构建类型。选择不同的构建类型(如 user 和 userdebug)会影响编译结果的特性和用途。以下是 rk3568_r-user 和 rk3568_r-userdebug 之间的主要区别: user 构建类型 (rk3568_r-user): 目标用户:最终用户(消费者)。…

undetected_chromedriver驱动浏览器结束报错OSError: [WinError 6] 句柄无效

undetected_chromedriver驱动浏览器结束报错OSError: [WinError 6] 句柄无效 问题背景 使用undetected_chromedriver包驱动浏览器结束后报错句柄无效 Exception ignored in: <function Chrome.del at 0x000001DD50F07A60> Traceback (most recent call last): File “D:…