设计模式行为型——观察者模式

目录

什么是观察者模式

观察者模式的实现

观察者模式角色

观察者模式类图

观察者模式举例

观察者模式代码实现

观察者模式的特点

优点

缺点

使用场景

注意事项

实际应用


什么是观察者模式

        观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式的实现

观察者模式角色

  1. 主题角色(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
  2. 具体主题角色(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
  3. 观察者角色(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
  4. 具体观察者角色(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。

观察者模式类图

观察者模式举例

观察者模式代码实现

主题角色

package com.common.demo.pattern.observer;import java.util.Vector;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 主题角色* @date 2023/08/07 10:37:05*/
public abstract class Subject {private Vector<Observer> obs = new Vector();public void addObserver(Observer obs) {this.obs.add(obs);}public void delObserver(Observer obs) {this.obs.remove(obs);}protected void notifyObserver() {for (Observer o : obs) {o.update();}}public abstract void doSomething();
}

具体主题角色

package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体主题角色* @date 2023/08/07 10:39:23*/
public class ConcreteSubject extends Subject{@Overridepublic void doSomething(){System.out.println("被观察者事件发生改变");this.notifyObserver();}
}

观察者角色

package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 观察者角色 观察者接口* @date 2023/08/07 10:30:26*/
public interface Observer {void update();
}

具体观察者角色

package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体观察者角色 观察者角色A* @date 2023/08/07 10:40:54*/
public class ConcreteObserverA implements Observer{@Overridepublic void update() {System.out.println("观察者A收到信息,并进行业务处理");}
}
package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体观察者角色 观察者角色B* @date 2023/08/07 10:40:54*/
public class ConcreteObserverB implements Observer{@Overridepublic void update() {System.out.println("观察者B收到信息,并进行业务处理");}
}

测试类

package com.common.demo.pattern.observer;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 测试类* @date 2023/08/07 10:46:55*/
public class ClientTest {public static void main(String[] args) {Subject sub = new ConcreteSubject();sub.addObserver(new ConcreteObserverA());sub.addObserver(new ConcreteObserverB());sub.doSomething();}
}

测试截图

观察者模式的特点

优点

  1. 实现了松耦合:观察者模式可以将被观察者和观察者之间的耦合度降低,使得它们可以独立地进行扩展和修改。
  2. 支持广播通信:建立一套广播通信触发机制,被观察者可以同时通知多个观察者,从而支持广播通信的需求。
  3. 符合开闭原则:新增或删除观察者不会影响到被观察者和其他观察者的代码,符合开闭原则的要求。

缺点

  1. 观察者过多可能导致性能问题:如果观察者过多或者观察者的处理逻辑复杂,会影响到系统的性能,花费较多的时间。
  2. 观察者和被观察者直接关联:在一些情况下,观察者和被观察者之间的直接关联可能会导致设计上的困扰。
  3. 观察者和观察目标循环依赖:在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 
  4. 观察者对所观察的目标对象黑盒操作:无相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

  1. 当一个对象的改变需要通知其他对象,并且不希望将对象之间的耦合度过高时,可以考虑使用观察者模式。
  2. 当某个对象的状态改变需要引起一系列相关对象的更新时,不需要知道这些对象是谁,不需知道具体有多少对象有待改变,可以使用观察者模式。
  3. 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

注意事项

  1. 注意观察者和被观察者的关联方式:可以通过接口或抽象类定义观察者接口,使得被观察者只与接口进行交互,而不依赖于具体的观察者实现类。
  2. 避免循环依赖:观察者和被观察者之间应该避免出现循环依赖的情况,否则可能导致无限循环的通知。
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,可采用异步方式进行通知。

实际应用

  1. 网络订阅服务:订阅者可以订阅感兴趣的内容,当内容更新时,订阅者会收到通知。
  2. 消息中间件:多个消息消费者可以同时监听一个消息主题,当主题发布消息时,所有消费者都会接收到通知并处理消息。
  3. GUI界面组件:GUI界面中的事件监听机制就是一种观察者模式的实现。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

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

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

相关文章

【工程优化问题】基于多种智能优化算法的压力容器设计问题研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

VMware16.2.5版本虚拟机克隆服务步骤(图解版)

目录 一、VMware16.2.5版本虚拟机克隆服务具体步骤二、VMware16.2.5版本虚拟机克隆服务后如何配置静态ip 一、VMware16.2.5版本虚拟机克隆服务具体步骤 1.1、先停止需要克隆的服务&#xff0c;选中需要克隆的服务——>鼠标右键选择【电源】——>【关闭客户机】&#xff…

【Linux升级之路】5_基础IO

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux升级之路】 ✒️✒️本篇内容&#xff1a;文件操作&#xff0c;文件管理&#xff0c;重定向&#xff0c;简易shell添加重定向功能&#xff0c;文件属…

骑士牛(BFS)

题面 john用他的一头母牛和Don先生交换了一头“骑士牛”。这头牛有一个独特的能力——在牧场中能像中国象棋中的马一样跑跳&#xff08;会中国象棋吗&#xff1f;不会&#xff1f;注意&#xff1a;本题不考虑马被“蹩脚”的情况&#xff09;。 当然&#xff0c;这头牛不能跳到岩…

python接口自动化之正则用例参数化

前言 ​ 我们在做接口自动化的时候&#xff0c;处理接口依赖的相关数据时&#xff0c;通常会使用正则表达式来进行提取相关的数据。 ​ 正则表达式&#xff0c;又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(Regular Expression&#xff0c;在代码中常简写…

【搜索框的匹配功能】

功能需求&#xff1a; 1. 输入关键字的同时&#xff0c;以下拉列表的形式显示匹配的内容&#xff1b; 2. 点击下拉列表的选项&#xff0c;跳转到对应的新的页面 注意&#xff1a;这里读取data.txt&#xff08;检索的文件对象&#xff09;&#xff0c;会存在跨域的问题&#x…

瞅一眼nginx

目录 &#x1f9ac;什么是nginx? &#x1f9ac;nginx配置官方yum源&#xff1a; &#x1f9ac;nginx优点 &#x1f9ac;nginx 缺点 &#x1f9ac;查看nginx默认模块 &#x1f40c;nginx新版本的配置文件&#xff1a; &#x1f40c;nginx目录索引 &#x1f40c;nginx状态…

【C++】开源:ceres和g2o非线性优化库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍ceres和g2o非线性优化库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

IT 基础架构自动化

什么是 IT 基础架构自动化 IT 基础架构自动化是通过使用技术来控制和管理构成 IT 基础架构的软件、硬件、存储和其他网络组件来减少人为干预的过程&#xff0c;目标是构建高效、可靠的 IT 环境。 为什么要自动化 IT 基础架构 为客户和员工提供无缝的数字体验已成为企业的当务…

【网络安全】等保测评系列预热

【网络安全】等保测评系列预热 前言1. 什么是等级保护&#xff1f;2. 为什么要做等保&#xff1f;3. 路人甲疑问&#xff1f; 一、等保测试1. 渗透测试流程1.1 明确目标1.2 信息搜集1.3 漏洞探索1.4 漏洞验证1.5 信息分析1.6 获取所需1.7 信息整理1.8 形成报告 2. 等保概述2.1 …

Nginx代理接口访问返回404

Nginx代理接口访问返回404 一、背景 因为不同业务系统间有接口调用&#xff0c;存在跨域问题&#xff0c;为了解决同源策略&#xff0c;需要将接口通过nginx去转发&#xff0c;但是配置完后通过postman请求一直存在访问404的问题。 访问地址&#xff1a;https://a.test.com/n…

元宇宙3D数字虚拟客服打造年轻化、数字化营销新品牌

融合了元宇宙、AI和云计算等技术的虚拟数字人&#xff0c;成为元宇宙数字内容交互的载体&#xff0c;将现实世界中的人与虚拟数字世界的场景、模型及产品链接起来&#xff0c;特别是为电力企业打造的电力元宇宙平台&#xff0c;带来营销宣传多重好处的同时&#xff0c;树立了数…

TOPIAM 社区版 1.0.0 发布,开源 IAM/IDaaS 企业身份管理平台

文章目录 产品概述系统架构功能列表管理端门户端 技术架构后续规划相关地址 ​Hi&#xff0c;亲爱的朋友们&#xff0c;今天是传统 24 节气中的立秋&#xff0c;秋天是禾谷成熟、收获的季节。经过长时间优化和迭代&#xff0c;TOPIAM 企业身份管控平台也迎来了当下的成长和收获…

现代C++中的从头开始深度学习:【5/8】卷积

一、说明 在上一个故事中&#xff0c;我们介绍了机器学习的一些最相关的编码方面&#xff0c;例如 functional 规划、矢量化和线性代数规划。 现在&#xff0c;让我们通过使用 2D 卷积实现实际编码深度学习模型来开始我们的道路。让我们开始吧。 二、关于本系列 我们将学习如何…

第17章-Spring AOP经典应用场景

文章目录 一、日志处理二、事务控制三、参数校验四、自定义注解五、AOP 方法失效问题1. ApplicationContext2. AopContext3. 注入自身 六、附录1. 示例代码 AOP 提供了一种面向切面操作的扩展机制&#xff0c;通常这些操作是与业务无关的&#xff0c;在实际应用中&#xff0c;可…

Netty框架自带类DefaultEventExecutorGroup的作用,用来做业务的并发

一、DefaultEventExecutorGroup的用途 DefaultEventExecutorGroup 是 Netty 框架中的一个类&#xff0c;用于管理和调度事件处理器&#xff08;EventExecutor&#xff09;的组。在 Netty 中&#xff0c;事件处理是通过多线程来完成的&#xff0c;EventExecutor 是处理事件的基…

数据结构 二叉树(一篇基本掌握)

绪论 雄关漫道真如铁&#xff0c;而今迈步从头越。 本章将开始学习二叉树&#xff08;全文共一万两千字&#xff09;&#xff0c;二叉树相较于前面的数据结构来说难度会有许多的攀升&#xff0c;但只要跟着本篇博客深入的学习也可以基本的掌握基础二叉树。 话不多说安全带系好&…

Clickhouse 优势与部署

一、clickhouse简介 1.1 clickhouse介绍 ClickHouse的背后研发团队是俄罗斯的Yandex公司&#xff0c;2011年在纳斯达克上市&#xff0c;它的核心产品是搜索引擎。我们知道&#xff0c;做搜索引擎的公司营收非常依赖流量和在线广告&#xff0c;所以做搜索引擎的公司一般会并行推…

QT图形视图系统 - 使用一个项目来学习QT的图形视图框架 - 终篇

QT图形视图系统 - 终篇 接上一篇&#xff0c;我们需要继续完成以下的效果&#xff1b; 先上个效果图&#xff1a; 修改背景&#xff0c;使之整体适配 上一篇我们绘制了标尺&#xff0c;并且我们修改了放大缩小和对应的背景&#xff0c;整体看来&#xff0c;我们的滚动条会和…