设计模式——观察者模式

观察者模式(世界线的观测者)

定义

观察者模式(Observer Partern)也叫做发布/订阅模式(Publish/Subscribe),一种以监听为核心的设计模式。

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

优缺点、应用场景

优点

  1. 观察者和被观察者之间是抽象耦合。如此不论是增加观察者还是被观察者都非常容易拓展,而且都是Java中已经实现的抽象层级定义。
  2. 建立一套触发机制。蝴蝶效应,一举一动都会影响世界线的变动。

缺点

需要考虑开发和运行效率,一般会采用异步的方式。

应用场景

  1. 关联行为场景。关联行为是可拆分的,而不是耦合的“组合”关系
  2. 事件多级触发场景
  3. 跨系统的消息交换场景,如消息队列的上下游消息的传递。

代码模拟场景

战国时期秦国的丞相李斯想要监控韩非子的一举一动,于是安插间谍在韩非子周围

实验小结

  1. 将观察者嵌入到被观察者类中确实能够实现监控,但是不利于观察者的拓展
  2. 现需要两个接口Observer和Observable
  3. 前者是观察者实现的,需要重写update方法,决定监听到方法执行后的逻辑
  4. 后者是被观察者实现的,将所有参与观察的观察者封装成集合,执行方法时统一通知。
    然后去欺骗世界吧,命运石之门必定存在,EL PSY CONGROO

观察者模式

UML图

在这里插入图片描述

观察者接口与实现类

/*** 观察者接口*/
public interface Observer {// 被观察者操作则通知public void update(String context);
}public class LiSi implements Observer {// 若韩非子有动向,立即知晓@Overridepublic void update(String context) {System.out.println("李斯:观察到韩非子活动,开始向上级汇报");this.reportToEmperor(context);System.out.println("李斯:汇报完毕。。\n");}private void reportToEmperor(String context) {System.out.println("李斯:报~~~!韩非子有活动了----->" + context);}
}/*** 张苍,同韩非子、李斯为荀子的弟子* 助刘邦统一,官至丞相*/
public class ZhangCang implements Observer {@Overridepublic void update(String context) {System.out.println("张苍:观察到韩非子活动,开始♂摸索");jieBroQuotation(context);System.out.println("张苍:摸索♂结束");}public void jieBroQuotation(String context) {System.out.println("张苍:韩非子有活动?让我康康!!------->" + context);}
}

被观察者接口及实现类

/*** 被观察者接口*/
public interface Observable {// 增加一个观察者public void addObserver(Observer observer);// 删除一个观察者public void deleteObserver(Observer observer);// 被观察者操作时,通知观察者public void notifyObservers(String context);
}

被观察者个性接口

/*** 被观察者接口*/
public interface IHanFeiZi {// 韩非子吃早餐public void haveBreakfast();// 韩非子玩♂游♂戏public void haveFun();
}public class HanFeiZi implements Observable,IHanFeiZi {// 所有的观察者放在一个集合中private List<Observer> observerList = new ArrayList<>();// 韩非子要吃饭了@Overridepublic void haveBreakfast() {System.out.println("韩非子:开始吃饭了。。。");this.notifyObservers("韩非子在吃饭");}// 韩非子要玩♂游♂戏了@Overridepublic void haveFun() {System.out.println("韩非子:玩♂游♂戏");this.notifyObservers("韩非子在玩♂游♂戏");}// 添加一个观察者@Overridepublic void addObserver(Observer observer) {this.observerList.add(observer);}// 删除一个观察者@Overridepublic void deleteObserver(Observer observer) {this.observerList.remove(observer);}// 通知观察者们@Overridepublic void notifyObservers(String context) {for (Observer observer : observerList) {observer.update(context);}}
}

入口类方法

public static void realObserve() {// 观察者阵容Observer liSi = new LiSi();Observer zhangCang = new ZhangCang();// 被观察者HanFeiZi hanFeiZi = new HanFeiZi();hanFeiZi.addObserver(liSi);hanFeiZi.addObserver(zhangCang);// 被观察者开始动作hanFeiZi.haveBreakfast();hanFeiZi.haveFun();
}

结果

在这里插入图片描述

参考书籍

秦小波《设计模式之禅》

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

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

相关文章

UG\NX二次开发 获取对象的边界包容盒 UF_MODL_ask_bounding_box

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 获取对象的边界包容盒 UF_MODL_ask_bounding_box,只能得到绝对坐标系下的边界包容盒,速度快,结果不精确。 效果: 代码: //UF_MODL_ask_bounding_box #include "me.hpp" #include &…

vscode 端口转发实现端口映射,实现端口自由

用vscode连接server进行开发&#xff0c; 是非常方便的&#xff0c;但很多时候&#xff0c;server的端口开放的很有限&#xff0c;那么就可以利用vscode进行端口映射 举一个应用场景&#xff1a; 先通过A利用vscode 连接B&#xff0c;然后再vscode 的port窗口进行端口转发&…

美工面试题目(合集)

美工面试题目篇1 1、目前常用的WEB标准静态页面语言是。(4分) 2、改变元素的外边距用&#xff0c;改变元素的内填充用。(6分) 3、在Table中&#xff0c;TR是&#xff0c;TD是。(6分) 4、如果给一行两列的表格(table)定义高度样式&#xff0c;在标签中定义最合理&#xff0c…

springboot人事管理系统

本项目在开发和设计过程中涉及到原理和技术有: B/S、java技术和MySQL数据库等等&#xff1b;将按以下章节进行开发设计&#xff1b; 绪论&#xff1b;剖析项目背景,说明研究的内容。 开发技术&#xff1b;系统主要使用了java技术&#xff0c;b/s模式和myspl数据库&#xff0c;并…

从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别

目录 1. 关联式容器 1.1 树形结构的关联式容器 2. set的相关介绍 2.1 set的构造和迭代器 2.2 set的容量和操作函数 2.3 set使用代码 2.4 multiset使用 3. map的相关介绍 3.1 键值对 3.2 map的构造和迭代器 3.3 map的容量和操作函数 3.4 map使用代码 3.5 multimap使…

python脚本(Word转PDF格式小工具)

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QMessageBox from PyQt5.QtCore import Qt import sys import os from comtypes import client#文件转换脚本 class FileDropWidget(QWidget):def __init__(self):super().__init__()self.initUI()de…

应用于智能眼镜上实现检测功能的距离传感芯片

随着智能穿戴设备的发展&#xff0c;各种新型的电子产品不断被研发出来&#xff0c;诸如智能头盔、智能手表、智能手环等等&#xff0c;智能眼镜就是其中一种&#xff0c;国内华为、小米相继推出智能产品。 智能眼镜具有和智能耳机相似的功能&#xff0c;不仅保留眼镜本身功能…

十七、web网页像素知识

目录&#xff1a; 像素视口 一、像素 像素&#xff1a;- 屏幕是由一个个发光的小点构成&#xff0c;这一个个的小点就是像素- 分辨率&#xff1a;1920 x 1080 说的就是屏幕中小点的数量- 在前端开发中像素要分成两种情况讨论&#xff1a;css像素和物理像素- 物理像素&#xff…

雪花算法 — 集群高并发情况下如何保证分布式唯一全局ID生成?

雪花算法 问题 为什么需要分布式全局唯一ID以及分布式ID的业务需求 在复杂分布式系统中&#xff0c;往往需要对大量的数据和消息进行唯一标识&#xff1a; 如在美团点评的金融、支付、餐饮、酒店猫眼电影等产品的系统中数据逐渐增长&#xff0c;对数据库分库分表后需要有一…

图像分割的简史:从CNN到掩模R-CNN

一、说明 在 Athelas&#xff0c;我们使用卷积神经网络 &#xff08;CNN&#xff09; 不仅仅是分类&#xff01;在这篇文章中&#xff0c;我们将看到如何在图像实例分割中使用CNN&#xff0c;并取得很好的效果。 自从 Alex Krizhevsky、Geoff Hinton 和 Ilya Sutskever 在 2012…

Linux基础服务10——虚拟化kvm

文章目录 一、基本了解二、安装kvm2.1 部署准备2.2 安装基础服务2.3 安装web管理服务 三、web界面管理3.1 添加kvm主机3.2 存储管理3.2.1 上传镜像3.2.2 扩容存储池 3.3 网络管理3.4 创建虚拟机3.5 报错处理3.5.1 Server disconnected3.5.1 文件句柄问题 一、基本了解 什么是虚…

常用分类损失CE Loss、Focal Loss及GHMC Loss理解与总结

一、CE Loss 定义 交叉熵损失&#xff08;Cross-Entropy Loss&#xff0c;CE Loss&#xff09;能够衡量同一个随机变量中的两个不同概率分布的差异程度&#xff0c;当两个概率分布越接近时&#xff0c;交叉熵损失越小&#xff0c;表示模型预测结果越准确。 公式 二分类 二…