二十三种设计模式全面解析-当你的对象需要知道其他对象的状态变化时,观察者模式是你的救星!


在软件设计的世界中,有一种设计模式以其简洁而强大的特性闪耀着光芒,它就是——观察者模式(Observer Pattern)。这个模式它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,为我们创造了一种优雅的编程体验。本文将带你深入探讨,观察者模式的神秘面纱,揭示其强大之处,让你在面对复杂系统时能游刃有余。


1、什么是观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象发生变化时,它会通知所有的观察者对象,使它们能够自动更新自己。在观察者模式中,主题对象和观察者对象之间是松耦合的,它们之间并不直接依赖,而是通过抽象的接口或抽象类进行交互。


2、适用场景

观察者模式适用于以下场景:

  • 当一个对象的改变需要同时改变其他对象的时候。
  • 当一个对象需要将自己的改变通知其他对象,而又不希望知道具体有多少个对象需要通知时。
  • 当一个对象需要通知其他对象,但是又希望这些对象是动态的,即不需要在编译时就确定下来。

例如,一个新闻发布机构可以作为主题对象,而订阅该机构新闻的用户可以作为观察者对象。当新闻发布机构发布新闻时,所有订阅该机构新闻的用户都会收到通知。


3、技术要点

观察者模式包含以下几个核心角色:

  • 主题(Subject):维护一组观察者对象,提供注册和删除观察者对象的方法,并通知观察者对象状态变化。
  • 观察者(Observer):定义了一个更新接口,用于在主题状态变化时接收通知。
  • 具体主题(Concrete Subject):继承或实现主题接口,实现注册、删除和通知观察者对象的方法。
  • 具体观察者(Concrete Observer):继承或实现观察者接口,实现更新接口,以便在主题状态变化时更新自己的状态。

4、观察者模式案例

import java.util.ArrayList;
import java.util.List;interface Observer {public void update(String message);
}interface Subject {public void attach(Observer observer);public void detach(Observer observer);public void notifyObservers();
}class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<Observer>();private String message;public void attach(Observer observer) {observers.add(observer);}public void detach(Observer observer) {observers.remove(observer);}public void notifyObservers() {for (Observer observer : observers) {observer.update(message);}}public void setMessage(String message) {this.message = message;notifyObservers();}
}class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}public void update(String message) {System.out.println(name + " received message: " + message);}
}public class ObserverPatternDemo {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer1 = new ConcreteObserver("Observer 1");ConcreteObserver observer2 = new ConcreteObserver("Observer 2");ConcreteObserver observer3 = new ConcreteObserver("Observer 3");subject.attach(observer1);subject.attach(observer2);subject.setMessage("Hello World!");subject.detach(observer2);subject.attach(observer3);subject.setMessage("Goodbye World!");}
}

在这里插入图片描述


在上面的代码中,我们定义了一个 Subject 接口和一个 Observer 接口。

Subject 接口定义了注册、删除和通知观察者的方法,而 Observer 接口定义了更新方法。


然后我们定义了一个具体的主题类 ConcreteSubject,它维护了一个观察者列表,并实现了 Subject 接口中的方法。

我们还定义了一个具体的观察者类 ConcreteObserver,它实现了 Observer 接口中的更新方法。在 ObserverPatternDemo 类中,我们创建了一个具体的主题对象 subject 和三个具体的观察者对象 observer1observer2observer3


我们首先将 observer1observer2 注册到 subject 中,然后改变 subject 的状态,这会导致 observer1observer2 的更新方法被调用。

接着我们将 observer2subject 中删除,并将 observer3 注册到 subject 中,然后再次改变 subject 的状态,这会导致 observer1observer3 的更新方法被调用。


这个案例代码展示了如何使用观察者模式来实现对象之间的松耦合,并且可以在运行时动态地选择不同的观察者,而不需要修改客户端代码。


总结:

观察者模式是一种非常有用的设计模式,它可以帮助我们实现对象之间的松耦合,让多个对象能够同时监听某一个主题对象。


然而,设计模式世界中还有许多其他精彩的故事等待我们探索。在下一篇博文中,我们将深入研究另一个引人入胜的设计模式,为你带来更多惊喜。敬请期待!


好了,今天的分享到此结束。如果觉得我的博文帮到了您,您的点赞和关注是对我最大的支持。如遇到什么问题,可评论区留言。


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

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

相关文章

035、目标检测-物体和数据集

之——物体检测和数据集 目录 之——物体检测和数据集 杂谈 正文 1.目标检测 2.目标检测数据集 3.目标检测和边界框 4.目标检测数据集示例 杂谈 目标检测是计算机视觉中应用最为广泛的&#xff0c;之前所研究的图片分类等都需要基于目标检测完成。 在图像分类任务中&am…

OpenGL_Learn13(材质)

1. 材质 cube.vs #version 330 core layout (location 0) in vec3 aPos; layout (location 0 ) in vec3 aNormal;out vec3 FragPos; out vec3 Normal;uniform mat4 model; uniform mat4 view; uniform mat4 projection;void main() {FragPosvec3(model*vec4(aPos,1.0));Norma…

【Java程序员面试专栏 专业技能篇】Java SE核心面试指引

关于Java SE部分的核心知识进行一网打尽&#xff0c;包括四部分&#xff1a;基础知识考察、面向对象思想、核心机制策略、Java新特性&#xff0c;通过一篇文章串联面试重点&#xff0c;并且帮助加强日常基础知识的理解&#xff0c;全局思维导图如下所示&#xff1a;

STM32-基本定时器

一、基本定时器的作用 定时触发输出直接驱动DAC。 二、基本定时器的框图 以STM32F103系列为例&#xff0c;具体开发板请查看开发手册。 类别定时器总线位数计数方向预分频系数是否可以产生DMA捕获/比较通道互补输出基本定时器TIM6 / TIM7APB116位向上1~65536可以0无通用定时…

Yolov5安装运行过程中出现的问题

Yolov5安装运行过程中出现的问题合集 安装问题pip 安装 requirements.txtcmd下如何退出python&#xff1f;升级numpy protobuf版本过高AttributeError: Can’t get attribute ‘SPPF’ on <module ‘models.common’ from 地址找不到图片NameError: name warnings is not de…

Spring Cloud学习(九)【Elasticsearch 分布式搜索引擎01】

文章目录 初识 elasticsearch了解 ES倒排索引ES 的一些概念安装es、kibana安装elasticsearch部署kibana 分词器安装IK分词器ik分词器-拓展词库 索引库操作mapping 映射属性索引库的 CRUD 文档操作添加文档查看、删除文档修改文档Dynamic Mapping RestClient 操作索引库什么是Re…

后端老项目迁移方法

老项目迁移方法 需求&#xff1a; 因某个模块MySQL表结构、表关系 错乱复杂&#xff0c;而且其他模块的代码也在操作这个模块的数据库 耦合严重 导致Web工程代码紊乱、不易理解、性能低下&#xff0c; 故在 系统由A JavaWeb工程迁移至B工程 时&#xff0c;重构MySQL表结构、表…

计算机毕业设计选题推荐-个人健康微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

2023年【陕西省安全员B证】考试报名及陕西省安全员B证模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年陕西省安全员B证考试报名为正在备考陕西省安全员B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的陕西省安全员B证模拟试题祝您顺利通过陕西省安全员B证考试。 1、【多选题】《陕西省建设工程质量和…

【C++】容器string的构造函数和迭代器

目录 1 什么是string 2 迭代器 2.1 迭代器的使用 2.2 auto关键字以及代码可读性 3 构造函数 string - C Reference 1 什么是string 上图是C官网对于string的解释&#xff1a;string是表示字符序列的对象。 string本质是一个类&#xff0c;位于std的命名空间下&#xff0…

Android File Transfer(安卓文件传输工具)

Android File Transfer 是一款安卓文件传输工&#xff0c;它允许在Mac操作系统和Android设备之间进行文件传输。 该软件通过USB连接将文件从Mac电脑传输到连接的Android设备&#xff0c;或者反过来从Android设备传输文件到Mac电脑。这包括照片、视频、音乐、文档和其他文件类型…

从iddata函数生成的结构体数据中获取时间序列、输入序列和输出序列

从iddata函数生成的结构体数据中获取时间序列、输入序列和输出序列 在使用iddata函数生成结构体数据后&#xff0c;有时需要单独使用其中的时间序列&#xff0c;输入序列和输出序列&#xff0c;此时需要对iddata生成的数据进行分析&#xff0c;以获得所需数据。本文说明读取时…