【设计模式】之观察者模式

系列文章目录

  • 【设计模式】之装饰器模式
  • 【设计模式】之工厂模式(三种)
  • 【设计模式】之工厂模式(三种)

前言

今天给大家介绍另一种设计模式--观察者模式,有了解webscoket实现原理的小伙伴应该对这个设计模式不陌生。不清楚也没关系,今天就给大家介绍一下这个设计模式。🌈


一、什么是观察者模式

观察者模式是一种常见的设计模式,用于在对象之间建立一对多的依赖关系。在该模式中,一个目标对象管理所有依赖于它的观察者对象,并在其状态改变时主动发出通知。

在观察者模式中,主要有以下几个角色:

  1. Subject(目标/主题/可观察者)
  • 定义了被观察者需要实现的接口,通常包含添加、删除观察者以及通知所有观察者的方法。
  • 用来保存注册的观察者对象,它可以是一个具体的被观察对象,也可以是一个抽象类或接口。
  • 当其内部状态改变时,会通过某种方式(如调用方法)通知所有注册的观察者对象。
  1. Observer(观察者/监听者)
  • 定义了一个更新接口,使得在得到目标的改变通知时更新自己。
  • 可以是具体的观察者对象,也可以是一个抽象类或接口。
  • 实现了观察者接口的对象可以在目标对象改变时收到通知。
  1. ConcreteSubject(具体目标/具体可观察者)
  • 实现了目标接口,在内部状态改变时,会通知所有注册的观察者对象。
  • 通常包含有经常发生改变的数据。
  1. ConcreteObserver(具体观察者/具体监听者)
  • 实现了观察者接口,实现具体的更新方法,以便在得到目标的改变通知时执行具体的动作。
  • 根据需要,可以更新目标的状态或做某些动作。

UMl类图

二、有哪些应用场景

最常见的就是前后端实时通信的webscoket,观察者模式在其他实际应用中也具有广泛的应用场景,比如:

  1. 事件处理:观察者模式常被用于事件处理机制,其中观察者对象订阅特定事件,并在事件发生时接收通知并执行相应的操作。例如,在图形用户界面(GUI)框架中,按钮的点击事件、窗口的打开和关闭事件等都可以使用观察者模式进行处理。
  2. 消息通知:观察者模式在消息通知系统中得到广泛应用。当发布者发布新消息时,订阅该消息的观察者将收到通知并进行相应的处理。这种模式常见于聊天应用、社交媒体平台等需要实时消息传递的场景。
  3. 实时数据更新:在需要实时更新数据的应用中,观察者模式可以用于将数据源与数据消费者连接起来。当数据源的数据发生变化时,观察者可以自动获取最新的数据并进行处理。
  4. 股票市场:股票市场应用程序可以使用观察者模式来监测股票价格变化,并将这些变化通知给投资者。
  5. 游戏开发:在游戏中,观察者模式可用于处理各种事件,如玩家输入、碰撞检测、角色状态变化等。当游戏角色的位置发生变化时,所有观察者(例如地图)都能收到通知,从而更新图形显示。
  6. 网络通信:在网络应用中,观察者模式可用于实现即时通信系统,其中用户之间的消息传递可以通过观察者模式来实现。

三、案例

我就以取快递这个案例为例,首先驿站拿到我们的快递后会给我们发送取件码,通知我们取件,然后我们接收到通知后,拿着取件码取件;这个过程中,驿站就是被观察者,我们自己就是观察者。接下来我们用代码实现这个过程。

首先,定义观察者接口或者抽象类

public abstract class Customer {public abstract void update();
}

具体观察者

public class CustomerA extends Customer{@Overridepublic void update() {System.out.println("顾客A的快递已送达");}
}public class CustomerB extends Customer{@Overridepublic void update() {System.out.println("顾客B的快递已送达");}
}

 定义主题或目标接口

public interface Subject {void registerCustomer(Customer o);void removeCustomer(Customer o);void notifyCustomers();
}

 具体观察者

public class PostStation implements Subject{private List<Customer> customerList ;public PostStation(){this.customerList = new ArrayList<>();}//添加顾客@Overridepublic void registerCustomer(Customer o) {customerList.add(o);}//删除顾客@Overridepublic void removeCustomer(Customer o) {customerList.remove(o);}//通知所有顾客@Overridepublic void notifyCustomers() {for (Customer customer : customerList){customer.update();}}//对外提供取快递方法public void PostExpress(){this.notifyCustomers();}
}

测试

 void test1(){//创建一个驿站PostStation postStation = new PostStation();Customer customerA = new CustomerA();Customer customerB = new CustomerB();//添加两位顾客postStation.registerCustomer(customerA);postStation.registerCustomer(customerB);//通知所以顾客取快递postStation.notifyCustomers();}

总结

优点

  •  降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 目标与观察者之间建立了一套触发机制,使得当目标状态改变时,可以自动通知所有观察者。
  • 支持广播通信,目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
  • 满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,增加新的观察目标也很方便。

缺点

  • 观察者对象很多时,通知的发布会花费很长时间,影响程序的效率
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化

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

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

相关文章

2023年ICPC亚洲济南地区赛 G. Gifts from Knowledge

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, b…

【随笔】Git 高级篇 -- 上传命令的参数 (上)git push(三十六)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

飞天使-k8s知识点31-rancher的正确打开方式

文章目录 安装之前优化一下内核参数以及系统内核版本 rancher安装主要是使用以下命令nginx的配置为解决办法 安装之前优化一下内核参数以及系统内核版本 内核版本 4.17 cat > /etc/modules-load.d/iptables.conf <<EOF ip_tables iptable_filter EOF 然后重启服务器…

释放创造力,低成本实现您的梦想应用 —— 尽在我们的开源低代码平台!

在数字化时代&#xff0c;每个企业都渴望拥有自己的专属应用&#xff0c;但传统开发模式的高成本和技术壁垒让许多梦想搁浅。现在&#xff0c;我们为您带来了革命性的解决方案 —— 一个开源、免费、且功能强大的低代码开发平台&#xff01; 为什么选择我们的低代码平台&#…

游戏工作室如何利用惯性动作捕捉技术制作动画?

随着动捕设备不断进步和游戏行业的发展&#xff0c;惯性动作捕捉技术在游戏开发领域逐渐普及。惯性动作捕捉技术&#xff0c;可以精准捕捉现实世界中的真人动作&#xff0c;并将其精准应用于虚拟角色上&#xff0c;使游戏中的角色动作可以呈现出更写实、逼真和沉浸感&#xff0…

Power BI 可以取代 Excel 吗?

首先说明&#xff0c;Power BI并不能完全取代Excel。 Power BI和Excel虽然都是Microsoft推出的数据工具&#xff0c;但他们的设计目标并不相同&#xff0c;因此它们在数据分析和处理方面各自有独特的优势。两者更多是互补关系。 在做报表可视化方面Power BI确实优势明显&…

使用Vue连接Mqtt实现主题的订阅及消息发布

效果如下&#xff1a; 直接贴代码&#xff0c;本地创建一个html文件将以下内容贴入即可 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, …

【最大公约 调和级数 并集查找】2709. 最大公约数遍历

涉及知识点 最大公约 调和级数 并集查找&#xff08;并差集) 质数、最大公约数、菲蜀定理 LeetCode 2709. 最大公约数遍历 给你一个下标从 0 开始的整数数组 nums &#xff0c;你可以在一些下标之间遍历。对于两个下标 i 和 j&#xff08;i ! j&#xff09;&#xff0c;当且…

社区停车道闸系统价格一套多少?停车道闸系统十大品牌是哪些?

一、什么是停车道闸系统&#xff1f; 停车道闸系统是利用现代科学技术手段&#xff0c;对进出特定区域的车辆进行自动识别、控制和管理的系统。通常包含车牌识别、聚合收费、自动升降杆、车位引导等功能&#xff0c;可以有效提高车辆通行的安全性和管理效率。停车道闸系统广泛…

【Elasticsearch<五>末篇 ✈️✈️】结合 kibana 实现索引中 IP 地址分布地图可视化

目录 &#x1f44b;前言 &#x1f440;一、ES 地理位置基本了解 &#x1f331;二、IP 地址地图可视化 2.1 创建预处理通道 2.2 创建索引库 2.3 插入一条数据 2.4 观察写入后的数据 2.5 可视化展示 &#x1f604;三、章末 &#x1f44b;前言 继前面了解 Elasticsearch 的安…

向量数据库:PGVector

一、PGVector 介绍 PGVector 是一个基于 PostgreSQL 的扩展插件&#xff0c;为用户提供了一套强大的向量存储和查询的功能&#xff1a; 精确和近似最近邻搜索单精度&#xff08;Single-precision&#xff09;、半精度&#xff08;Half-precision&#xff09;、二进制&#xff…

鸿蒙内核源码分析(环境脚本篇) | 编译鸿蒙原来如此简单

很香的 Docker 如果只是为了编译鸿蒙,初级的接触鸿蒙,docker是很香的,从第一次接触docker就对它爱不释手, 脏活累活它干了,少了太多的麻烦. docker 编译鸿蒙看编译环境篇就行了, L1 和 L2 都编译通过了.如果要深入的了解鸿蒙,比如调试鸿蒙的代码或编译工具,就需要另辟蹊径了. …