设计模式使用场景实现示例及优缺点(行为型模式——观察者模式)

阿尔法的身体内部有一个智能芯片,这个芯片能够根据环境和需求自动改变它的行为模式。当阿尔法需要完成不同任务时,它的内部状态会发生变化,进而改变它的行为,就像是它变成了另一个机器人一样。

一天,智能城的市长接到一个紧急消息:城市的能源核心出了问题,导致整个城市即将陷入黑暗。市长知道只有阿尔法才能解决这个问题,于是他立刻派人去找阿尔法。

阿尔法接到任务后,立即进入“修理模式”。在修理模式下,阿尔法的内部状态变为“工程师状态”,它的手臂变成了各种工具,眼睛变成了高精度的扫描仪。阿尔法迅速来到了能源核心,开始检测问题所在。

经过一番检查,阿尔法发现问题出在能源核心的控制系统上。它决定进入“编程模式”。在编程模式下,阿尔法的内部状态变为“程序员状态”,它的手指变成了键盘和电缆接口,能够直接连接到控制系统并进行编程。

阿尔法快速编写了一段修复程序,上传到控制系统中。随着程序的运行,能源核心渐渐恢复了正常,整个智能城重新亮起了光芒。

然而,阿尔法的任务并没有结束。智能城的一所学校发生了火灾,学生们被困在教学楼里。阿尔法接到新的任务后,立即进入“救援模式”。在救援模式下,阿尔法的内部状态变为“救援状态”,它的身体变得更加坚固,装备了各种救援工具和灭火设备。

阿尔法迅速赶到现场,使用灭火器扑灭了火焰,随后用强有力的臂膀破开被困学生们的教室门,将他们一个个安全地带了出来。

观察者模式(Observer Pattern)

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将状态相关的行为封装在状态对象中,使得当对象的内部状态改变时,其行为也会随之改变,类似于它改变了其类。

核心组件

  • Subject(主题):主题保存了一组观察者,提供用于增加或删除观察者的接口。
  • Observer(观察者):为那些在主题状态改变时需要获得通知的对象定义一个更新接口。
  • ConcreteSubject(具体主题):存储具体观察者关心的数据,发送通知给观察者,通常包含对具体数据的增删改操作。
  • ConcreteObserver(具体观察者):实现观察者接口,以便在得到通知时更新自身。

适用场景

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时
    • 观察者模式允许你独立地扩展或复用核心功能。
  2. 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要改变时
    • 观察者模式可以让你在不修改这些类的前提下增加新的观察者。
  3. 当一个对象必须通知其他对象,但你希望避免做成这些对象之间的紧密耦合时
    • 观察者模式提供了一种松耦合的设计解决方案。

实现实例

以新闻应用为例,其中新闻发布系统(主题)需要通知所有订阅者(观察者)新闻更新。

主题接口(Subject Interface)

定义了附加和删除观察者的方法,以及通知观察者的方法。

public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}

具体主题(Concrete Subject)

存储状态,并在状态改变时通知观察者。

public class NewsAgency implements Subject {private List<Observer> observers = new ArrayList<>();private String news;public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {observers.remove(o);}public void notifyObservers() {for (Observer observer : observers) {observer.update(news);}}public void setNews(String news) {this.news = news;notifyObservers();}
}

观察者接口(Observer Interface)

定义更新接口,用于获取状态改变通知。

public interface Observer {void update(String news);
}

具体观察者(Concrete Observer)

实现观察者接口,根据通知更新自己。

public class NewsChannel implements Observer {private String news;@Overridepublic void update(String news) {this.news = news;System.out.println("News Updated: " + news);}
}

客户端代码(Client Code)

演示如何使用观察者模式。

public class Client {public static void main(String[] args) {NewsAgency newsAgency = new NewsAgency();NewsChannel channel = new NewsChannel();newsAgency.registerObserver(channel);newsAgency.setNews("New update on AI technology!");}
}

优缺点

优点
  1. 支持广播通信
    • 观察者模式提供了一种订阅机制,可以实现消息的广播。
  2. 应用松耦合
    • 主题与观察者之间使用抽象耦合,可以轻松地添加新的观察者。
缺点
  1. 可能引发无序的更新
    • 如果观察者的更新方法引发循环依赖,可能导致系统行为难以预测。
  2. 当观察者和主题之间的依赖关系复杂时,可能需要额外的维护成本

类图

+----------------+         +------------------+
|   Subject      |-------->|   Observer       |
+----------------+         +------------------+
| + registerObserver()     | + update()       |
| + removeObserver()       |                  |
| + notifyObservers()      +------------------+
+----------------+         |
|                |         |
+----------------+         ||+-------------------+--------+----------------+|                   |                 |                |
+---------------+ +-----------------+ +----------------+ +--------------+
|ConcreteSubject| |ConcreteObserver1| |ConcreteObserver2| | ...          |
+---------------+ +-----------------+ +----------------+ +--------------+
| + setNews()   | | + update()       | | + update()      | | + update()   |
+---------------+ +-----------------+ +----------------+ +--------------+

总结

观察者模式提供了一种优雅的方式来实现对象间的通信,特别适用于状态变化需要通知多个对象的场景。通过将主题与观察者解耦,增加了系统的灵活性和可扩展性,同时也需注意避免循环依赖和更新顺序问题。

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

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

相关文章

多种方式实现 元素高度丝滑的从0-1显示出来

选择合适的方式&#xff0c;给用户更好的体验&#xff0c;多种方式实现 元素高度丝滑的从0-1显示出来。 能用 CSS 实现的动画&#xff0c;就不要采用 JS 去实现。 1、浏览器可以对CSS动画进行优化&#xff0c;其优化原理类似于requestAnimationFrame&#xff0c;会把每一帧的…

java基础学习:序列化之 - Fast serialization

在Java中&#xff0c;序列化是将对象的状态转换为字节流的过程&#xff0c;以便保存到文件、数据库或通过网络传输。Java标准库提供了java.io.Serializable接口和相应的机制来进行序列化和反序列化。然而&#xff0c;标准的Java序列化机制性能较低&#xff0c;并且生成的字节流…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

关于Kafka的17个问题

1.Kafka 的设计时什么样的呢&#xff1f; Kafka 将消息以 topic 为单位进行归纳 将向 Kafka topic 发布消息的程序成为 producers. 将预订 topics 并消费消息的程序成为 consumer. Kafka 以集群的方式运行&#xff0c;可以由一个或多个服务组成&#xff0c;每个服务叫做一个…

前端css常用笔记

文章目录 一、样式二、vue笔记2.1、组件之间的通信2.1.1 子组件调用父组件的方法2.1.2 父组件调用子组件的方法2.1.3 孙组件调用祖父组件方法的实现 2.2、使用若依时,node_nodules越来越大的问题2.3、echart笔记 一、样式 1 文字与图标对不齐的解决方法 /**给icon加上这个样式即…

mysql的索引事务和存储引擎

一、索引 1、索引 索引的概念 &#xff1a;索引是一个排序的列表&#xff0c;在列表当中存储索引的值以及索引值对应数据所在的物理行。 索引的引用&#xff1a; 使用索引之后&#xff0c;就不需要扫描全表来定位某行的数据。 加快数据库的查询速度。 索引可以是表中的一…

ubuntu 网络 通讯学习笔记2

1.ubuntu 网络常用命令 在Ubuntu中&#xff0c;有许多网络相关的常用命令。以下是一些主要命令及其用途&#xff1a; ifconfig&#xff1a;此命令用于显示和配置网络接口信息。你可以使用它来查看IP地址、子网掩码、广播地址等。 例如&#xff1a;ifconfig 注意&#xff1a…

在 K8s 上使用 KubeBlocks 提供的 MySQL operator 部署高可用 WordPress 站点

引言 WordPress WordPress 是全球最流行的内容管理系统&#xff08;CMS&#xff09;&#xff0c;自 2003 年发布以来&#xff0c;已成为网站建设的首选工具。其广泛的插件和主题生态系统使用户能够轻松扩展功能和美化外观。活跃的社区提供丰富的资源和支持&#xff0c;进一步…

[RK3588-Android12] 关于如何取消usb-typec的pd充电功能

问题描述 RK3588取消usb-typec的pd充电功能 解决方案&#xff1a; 在dts中fusb302节点下usb_con: connector子节点下添加如下熟悉&#xff1a; 打上如下2个补丁 diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index c8a4e57c9f9b..173f8cb7…

使用OpenCV寻找图像中的轮廓

引言 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它提供了大量的视觉处理功能&#xff0c;包括图像和视频捕获、特征检测与匹配、图像变换、图像分割、颜色空间转换等。在图像处理中&#xff0c;寻找图像中的…

electron项目中实现视频下载保存到本地

第一种方式&#xff1a;用户自定义选择下载地址位置 渲染进程 // 渲染进程// 引入 import { ipcRenderer } from "electron";// 列表行数据下载视频操作&#xff0c;diffVideoUrl 是视频请求地址 handleDownloadClick(row) {if (!row.diffVideoUrl) {this.$message…

【数字电路学习新助手】掌握电路仿真软件,开启数字电路知识的新篇章

在信息科技日新月异的今天&#xff0c;数字电路知识的重要性不言而喻。无论是通信工程、计算机科学与技术&#xff0c;还是电子信息技术等领域&#xff0c;数字电路都是基础中的基础。然而&#xff0c;对于初学者来说&#xff0c;数字电路的学习往往充满了挑战。幸运的是&#…

Axure中继器入门:打造你的动态原型

前言 中继器 是 Axure 中的一个高级功能&#xff0c;它能够在静态页面上模拟后台数据交互的操作&#xff0c;如增加、删除、修改和查询数据&#xff0c;尽管它不具备真实数据存储能力。 中继器就像是一个临时的数据库&#xff0c;为我们在设计原型时提供动态数据管理的体验&a…

中职省培丨2024年大数据技术中职教师专业技能培训班企业参观实践圆满结束

7月17日&#xff0c;“2024年大数据技术中职教师专业技能培训班&#xff08;省培&#xff09;”参训老师莅临广东泰迪智能科技股份有限公司产教融合实训中心开展企业参观实践。泰迪智能科技董事长张良均、中职业务部总监李振林、中职业务部经理黄炳德、校企合作经理吴桂锋及来自…

centos跳过首次创建用户

centos跳过首次创建用户 centos跳过首次创建用户 在安装系统后&#xff0c;登录的时候总是让新建一个普通用户&#xff0c;很是烦人&#xff0c;于是想办法解决一下 方法一 在CentOS上&#xff0c;图形化登录&#xff08;如GNOME&#xff09;通常要求您创建一个用户来登录。…

.net core appsettings.json 配置 http 无法访问

1、在appsettings.json中配置"urls": "http://0.0.0.0:8188" 2、但是网页无法打开 3、解决办法&#xff0c;在Program.cs增加下列语句 app.UseAntiforgery();

vue 如何做一个动态的 BreadCrumb 组件,el-breadcrumb ElementUI

vue 如何做一个动态的 BreadCrumb 组件 el-breadcrumb ElementUI 一、ElementUI 中的 BreadCrumb 定义 elementUI 中的 Breadcrumb 组件是这样定义的 <template><el-breadcrumb separator"/"><el-breadcrumb-item :to"{ path: / }">主…

爬虫的概念

爬虫&#xff08;Web Crawler 或 Web Spider&#xff09;是一种自动化脚本或程序&#xff0c;用于浏览万维网&#xff08;World Wide Web&#xff09;并抓取网页上的信息。它们按照设定的规则自动地访问互联网上的网页&#xff0c;提取所需的数据&#xff0c;如文本、图片、视频…

搭建七日杀服务端系统选择,系统如何选择

《七日杀》是一款集合了第一人称射击、恐怖生存、塔防与角色扮演要素于一身的开放世界僵尸游戏。玩家需要在美国亚历桑纳地区作为幸存者生存&#xff0c;并探究整个事件背后的真相。对于喜欢这款游戏的玩家来说&#xff0c;搭建自己的专属服务器不仅能降低延迟&#xff0c;还能…

精通Python数据可视化:Matplotlib柱状图、直方图与饼状图实战解析

精通Python数据可视化&#xff1a;Matplotlib柱状图、直方图与饼状图实战解析 引言 在数据分析和科学研究中&#xff0c;数据可视化扮演着至关重要的角色。Matplotlib是Python中一个广泛使用的绘图库&#xff0c;它提供了丰富的绘图功能和灵活的定制选项。本文将详细介绍如何…