13、设计模式之观察者模式

观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

介绍

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决: 一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用: 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决: 使用面向对象技术,可以将这种依赖关系弱化。

关键代码: 在抽象类里有一个 ArrayList 存放观察者们。

应用实例: 拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。

优点:

  • 1、观察者和被观察者是抽象耦合的。
  • 2、建立一套触发机制。

缺点:

  • 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项:

  • 1、JAVA 中已经有了对观察者模式的支持类。
  • 2、避免循环引用。
  • 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

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

主题(Subject): 也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
观察者(Observer): 观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
具体主题(Concrete Subject): 具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
具体观察者(Concrete Observer): 具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。

观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。

代码实现

以上课提问问题为例

首先定义抽象观察者,学生接口

/*** 抽象观察者*/
public interface Student {String getName();void answer(Question question);
}

然后定义具体观察者,张三、李四、王五

public class StuLiSi implements Student {@Overridepublic String getName() {return "李四";}@Overridepublic void answer(Question question) {System.out.println(getName()+"回答了问题:" + question.getContent());}
}public class StuWangWu implements Student {@Overridepublic String getName() {return "王五";}@Overridepublic void answer(Question question) {System.out.println(getName()+"回答了问题:" + question.getContent());}
}public class StuZhangSan implements Student {@Overridepublic String getName() {return "张三";}@Overridepublic void answer(Question question) {System.out.println(getName()+"回答了问题:" + question.getContent());}
}

然后定义一个问题类

public class Question {private String content;public Question( String content) {this.content = content;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}

然后定义抽象主题、课堂类

public interface Course {void addStu(Student student);void removeStu(Student student);void askAll(Question question);void ask(String stuName, Question question);
}

定义具体主题类、数学课

public class MathClass implements Course{private final List<Student> students;public MathClass() {students = new ArrayList<>();}@Overridepublic void addStu(Student student) {this.students.add(student);}@Overridepublic void removeStu(Student student) {this.students.remove(student);}@Overridepublic void askAll(Question question) {for (Student student : this.students) {student.answer(question);}}@Overridepublic void ask(String stuName, Question question) {for (Student student : this.students) {if (student.getName().equals(stuName)){student.answer(question);}}}
}

客户端

public class Client {public static void main(String[] args) {//创建主题Course mathClass = new MathClass();//创建观察者Student student1 = new StuZhangSan();Student student2 = new StuLiSi();Student student3 = new StuWangWu();//添加观察者mathClass.addStu(student1);mathClass.addStu(student2);mathClass.addStu(student3);Question question1 = new Question( "这道题有谁做出来了?");//通知所有观察者mathClass.askAll(question1);Question question2 = new Question( "你来回答一下这道题的解法?");//通知某一个观察者mathClass.ask("张三", question2);}
}

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

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

相关文章

从0开始linux(3)——如何读写文件

欢迎来到博主的专栏——从0开始linux 博主ID&#xff1a;代码小豪 文章目录 创建普通文件用文本编辑器nano写入文件如何读取文件cat命令less命令head和tail 我们前面已经了解和如何操作文件&#xff0c;但是目前认识的文件类型分为两类&#xff0c;一类是目录文件、另一类是普通…

【C#上位机应用开发实战】—— 通信模块的基础与实践

&#x1f680; 引言 在工业自动化、设备监控、物联网&#xff08;IoT&#xff09;等领域&#xff0c;上位机软件扮演着至关重要的角色。作为连接人与设备的桥梁&#xff0c;上位机软件不仅需要提供友好的用户界面&#xff0c;更需要具备高效、稳定的通信能力。今天&#xff0c…

ASP+ACCESS教师档案管理系统

3.1 系统功能模块图 3.2 E&#xff0d;R模型图 3.3 系统使用流程图 3.4 各个模块功能简介&#xff1a; 本系统分为五个功能模块&#xff0c;它们分别是教师信息录入模块、教师信息修改模块、教师信息查询模块、教师信息打印模块。 下面分别介绍各个模块的功能用途&#x…

第 398 场 LeetCode 周赛题解

A 特殊数组 I 模拟&#xff1a;遍历数组判断是否是一个特殊数组 class Solution { public:bool isArraySpecial(vector<int>& nums) {int r 0;while (r 1 < nums.size() && nums[r 1] % 2 ! nums[r] % 2)r;return r nums.size() - 1;} };B 特殊数组 I…

计网(部分在session学习章)

TCP/UDP TCP:面向连接,先三次握手建立连接,可靠传输。 UDP:无连接,不可靠,传递的快。 TCP可靠传输 1.分块编号传输; 2.校验和,校验首部和数据的检验和,检测数据在传输中的变化; 3.丢弃重复数据; 4.流量控制,TCP 利⽤滑动窗⼝实现流量控制。TCP的拥塞控制采⽤…

如何解决VSCode Git插件差异查看器 无法读取文件 Error: 无法解析不存在的文件 的问题

问题描述 问题&#xff1a;在使用VSCode的Git插件中的差异查看器时&#xff0c;有时会出现如下报错信息&#xff1a; 无法读取文件 git:/d:/Desktop//UIInput.js?{"path":"d:\\Desktop\\UIInput.js","ref":"~"} (Error: 无法解析不…

如何用正则表达式匹配中文和英文

在文本处理和自然语言处理的领域&#xff0c;准确地分割和匹配单词是至关重要的任务之一。对于处理包含多种语言&#xff08;如中英文混合&#xff09;的文本&#xff0c;常见的分词方法可能不够准确&#xff0c;特别是对汉字和英文单词的处理。本文将介绍如何使用正则表达式&q…

基于Matlab卷积神经网络人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别作为计算机视觉领域的关键技术之一&#xff0c;具有广泛的应用前景&#xff0c;如安全…

Add object from object library 从对象库中添加内置器件

Add object from object library 从对象库中添加内置器件 正文正文 对于 Lumerical,有些时候我们在使用中,可能需要从 Object library 中添加器件,通常我们的做法是手动添加。如下图所示,我们添加一个 Directional Coupler 到我们的工程文件中: 但是这种操作方式不够智能…

基于HTML5和CSS3搭建一个Web网页(二)

倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 网页描述 创建一个包含导航栏、主内容区域和页脚的响应式网页。 需求: 导航栏: 在页面顶部创建一个导航栏&#xff0c;包含首页、关于我们、服务和联系我们等链接。 设置导航栏样式&#xff0c;包括字体、颜色和背景颜…

会话机制:Cookie

1、cookie的作用 cookie和session机制其实都是为了保存会话的状态。 cookie是将会话的状态保存在浏览器客户端上。&#xff08;cookie数据存储在浏览器客户端上的。&#xff09; session是将会话的状态保存在服务器端上。&#xff08;session对象是存储在服务器上。&#xff…

上门服务系统开发|东邻到家系统|上门服务系统开发流程

上门服务小程序的开发流程是一个复杂且精细的过程&#xff0c;涉及到需求分析、设计规划、开发实施、测试验收以及上线运营等多个环节。下面将详细介绍上门服务小程序的开发流程&#xff0c;帮助读者全面了解并掌握其中的关键步骤。 一、需求分析 在开发上门服务小程序之前&am…

API攻击呈指数级增长,如何保障API安全?

从远程医疗、共享汽车到在线银行&#xff0c;实时API是构建数字业务的基础。然而&#xff0c;目前超过90%的基于Web的网络攻击都以API端点为目标&#xff0c;试图利用更新且较少为人所知的漏洞&#xff0c;而这些漏洞通常是由安全团队未主动监控的API所暴露&#xff0c;致使API…

24款奔驰GLE350升级原厂环视全景360影像 抬头显示HUD

奔驰GLE350原厂360全景影像的清晰度通常取决于车辆的具体型号和年份&#xff0c;以及安装的摄像头和显示屏质量。一般来说&#xff0c;原厂360全景影像系统会提供高清的影像&#xff0c;让驾驶者能够清晰地看到车辆周围的环境&#xff0c;帮助进行停车和转弯等操作抬头显示&…

AOP编程

AOP编程 AOP&#xff0c;面向切面编程&#xff0c;一种编程范式&#xff0c;指导开发者如何组织程序结构。 OOP&#xff0c;面向对象编程&#xff0c;一种编程思想。 AOP&#xff0c;提供了一种机制,可以将一些横切系统中多个模块的共同逻辑(如日志记录、事务管理、安全控制等…

WordPress搭建流程

1. 简介 WordPress 是一个 PHP 编写的网站制作平台。WordPress 本身免费,并且拥有众多的主题可以使用,适合用于搭建个人博客、公司官网、独立站等。 2. 环境准备 2.1 WordPress 下载 WordPress 可以在 Worpress中文官网 下载(如果后续要将后台调成中文的话,一定要从中文…

定时器

文章目录 11.11.21.31.41.5 22.12.2 基本定时器 框图2.32.42.4.12.4.22.4.32.4.42.4.52.4.6 2.5 定时器 溢出时间计算方法2.6 定时器 中断 实验配置步骤2.72.7.12.7.2 和42.7.32.7.52.7.6 33.13.23.2.1 时钟源3.2.23.2.43.2.6 3.33.43.4.13.4.23.4.33.4.43.4.53.4.5.13.4.5.23.…

机器学习实验------Adaboost算法

第1关:什么是集成学习 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 第2关: Boosting 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 第3关:Adaboost算法流程 任务描述 本关任务:用Python实现Adaboost,并通过鸢尾花数据集…

Uniapp自定义默认返回按钮回退页面

//自定义后退时的操作onBackPress() {this.back1();return true;}, methods: { //跳转到 tabBar 页面&#xff0c;并关闭其他所有非 tabBar 页面back1() {uni.switchTab({url: /pages/mangement/mangement});},//关闭所有页面&#xff0c;打开到应用内的某个页面。back1() {uni…

优雅的代码规范,提升代码质量

优雅的代码规范&#xff0c;提升代码质量 分类 编程技术 在软件开发中&#xff0c;优雅的代码规范可以帮助我们写出既美观又实用的代码。 以下是提升代码质量的建议性规范&#xff1a; 命名清晰&#xff1a;使用描述性强的命名&#xff0c;让代码自我解释。简洁性&#xff1…