当前位置: 首页 > news >正文

行为型-观察者模式

文章目录

  • 基本概念
    • 定义
    • 使用场景
    • 代码实现
  • 延伸阅读
    • java监听机制
    • spring监听机制

基本概念

定义

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。
观察者模式包含以下几个核心角色:
主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。

使用场景

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。通过这种事件触发的机制,将观察者和被观察者进行解耦。
注意事项:
1、JAVA 中已经有了对观察者模式的支持类。(Java中EventObject、EventListener)
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

代码实现

主题接口

/*** 抽象主题(抽象被观察者角色)*/
public interface Subject {/*** 所有抽象观察者角色的集合*/List<Observer> observerList = Lists.newArrayList();/*** 注册观察者* @param observer*/default void addObserver(Observer observer){observerList.add(observer);}/*** 取消注册* @param observer*/default void removeObserver(Observer observer){observerList.remove(observer);}/*** 通知所有观察者* @param content*/default void notifyAllObserver(String content){for (Observer observer: observerList){observer.recvMsg(content);}}}

观察者接口

/*** 观察者*/
public interface Observer {void recvMsg(String content);
}

具体被观察者

@Data
public class ConcreteSubject implements Subject<Observer> {private String msg;/*** 发送通知*/public void sendMsg(){System.out.println("ConcreteSubject send msg: " + this.msg);notifyAllObserver(msg);}
}

具体观察者

public class ConcreteObserver implements Observer {@Overridepublic void recvMsg(String content) {System.out.println("ConcreteObserver recv msg:" + content);}
}

测试

public class ObserverTest {public static void main(String[] args) {ConcreteSubject concreteSubject = new ConcreteSubject();concreteSubject.setMsg("important msg");concreteSubject.addObserver(new ConcreteObserver());concreteSubject.sendMsg();}
}

延伸阅读

java监听机制

一、创建事件对象

public class MusicEvent extends EventObject {public static final int STATE_OPEN = 1;public static final int STATE_CLOSE = -1;/*** 状态*/private int state;/*** Constructs a prototypical Event.** @param source the object on which the Event initially occurred* @throws IllegalArgumentException if source is null*/public MusicEvent(Object source) {super(source);}public MusicEvent(Object source, int state) {super(source);this.state = state;}public int getState() {return state;}public void setState(int state) {this.state = state;}
}

二、创建监听器

public interface MusicListener extends EventListener {void play(MusicEvent musicEvent);
}

CloseMusicListener实现

public class CloseMusicListener implements MusicListener{@Overridepublic void play(MusicEvent musicEvent) {if(musicEvent.getState() == MusicEvent.STATE_CLOSE){System.out.println("CloseMusicListener play: stop dance");}}
}

OpenMusicListener实现

public class OpenMusicListener implements MusicListener{@Overridepublic void play(MusicEvent musicEvent) {if(musicEvent.getState() == MusicEvent.STATE_OPEN){System.out.println("OpenMusicListener play: let us go dancing!");}}
}

三、定义事件源,管理监听器

public class EventSource {// 监听器列表,监听器注册入此列表public List<MusicListener> musicListenerList = new ArrayList<>();// 注册监听器public void addMusicListener(MusicListener musicListener) {musicListenerList.add(musicListener);}// 取消注册public void removeMusicListener(MusicListener musicListener) {musicListenerList.remove(musicListener);}// 接收外部事件public void notifyMusicListener(MusicEvent musicEvent) {for (MusicListener musicListener : musicListenerList){musicListener.play(musicEvent);}}
}

四、测试

public class MusicEventTest {public static void main(String[] args) {EventSource eventSource = new EventSource();eventSource.addMusicListener(new OpenMusicListener());eventSource.addMusicListener(new CloseMusicListener());eventSource.notifyMusicListener(new MusicEvent("开门事件", MusicEvent.STATE_OPEN));}
}

spring监听机制

一、创建事件对象,继承ApplicationEvent

@EqualsAndHashCode(callSuper = true)
public class MyEvent extends ApplicationEvent {private String context;public MyEvent(Object source) {super(source);}public String getContext() {return context;}public void setContext(String context) {this.context = context;}
}

二、定义监听器,实现ApplicationListener
MyApplication1

public class MyApplication1 implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent myEvent) {System.out.println("MyApplication1 event:" + myEvent.getContext());}
}

MyApplication2

public class MyApplication2 implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent myEvent) {System.out.println("MyApplication2 event:" + myEvent.getContext());}
}

三、事件通知

@Service
public class MyListenerService {@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;public void register(MyEvent event){applicationEventPublisher.publishEvent(event);}
}

相关文章:

行为型-观察者模式

文章目录 基本概念定义使用场景代码实现 延伸阅读java监听机制spring监听机制 基本概念 定义 观察者模式是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;其所有依赖者都会收到通知并自动更新。 观察者模式…...

《ElementPlus 与 ElementUI 差异集合》el-input 和 el-button 属性 size 有变化

差异 ** element-ui el-input、el-input-number 和 el-button 中&#xff0c;属性size 值是 medium / small / minielement-plus el-input、el-input-number 和 el-button 中&#xff0c;属性size 值是 large / default /small 如果你是自动升级&#xff0c;Vue3 系统会有如…...

pxe安装mini centos系统

一、准备工作 1、关闭防火墙和selinux systemctl stop firewalld && systemctl disable firewalldsetenforce 02、配置静态ip 需要在dhcp里面填写tftp配置&#xff0c;所以需要固定ip 二、dhcp安装配置 作用&#xff1a;给客户端提供ip地址&#xff0c;并告诉客户…...

Android studio 性能调试

一、概述 Android studio 的Profiler可用来分析cpu和memory问题&#xff0c;下来进行说明介绍。 二、Android studio CPU调试 从开发模拟器或设备中启动应用程序&#xff1b; 在 Android Studio 中&#xff0c;通过选择View > Tool Windows > Profiler启动分析器。 应…...

java8特性 stream流中map函数的使用

map 函数的作用就是针对管道流中的每一个数据元素进行转换操作。 例如 将集合中的每一个字符串&#xff0c;全部转换成大写&#xff01; List<String> collect alpha.stream().map(String::toUpperCase).collect(Collectors.toList()); //上面使用了方法引用&#xf…...

【Emgu CV教程】9.5、形态学常用操作之形态学梯度

文章目录 一、相关概念1.什么叫形态学梯度2.形态学梯度的函数 二、演示1.原始素材2.代码3.运行结果 一、相关概念 1.什么叫形态学梯度 形态学梯度&#xff0c;就是用膨胀的原始图像减去腐蚀的原始图像&#xff0c;所以它的特性就是去除前景物体的内部区域&#xff0c;只得到前…...

算法笔记之蓝桥杯pat系统备考(2)

算法笔记之蓝桥杯&pat系统备考&#xff08;1&#xff09; 文章目录 五、数学问题5.2最大公约数和最小公倍数5.2.1最大公约数5.2.2最小公倍数 5.3分数的四则运算5.3.1分数的表示与化简5.3.2分数的四则运算5.3.3分数的输出 5.4素数&#xff08;质数&#xff09;5.4.1[素数的…...

基于SpringBoot+Druid实现多数据源:注解+编程式

前言 本博客姊妹篇 基于SpringBootDruid实现多数据源&#xff1a;原生注解式基于SpringBootDruid实现多数据源&#xff1a;注解编程式基于SpringBootDruid实现多数据源&#xff1a;baomidou多数据源 一、功能描述 配置方式&#xff1a;配置文件中配置默认数据源&#xff0c…...

已解决org.apache.zookeeper.KeeperException.BadVersionException异常的正确解冲方法,亲测有效!!!

已解决org.apache.zookeeper.KeeperException.BadVersionException异常的正确解冲方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 总结 博主v&#xff1a;XiaoMing_Java 问题分析 在使用Apache ZooKeeper进行…...

数据结构:堆

堆的概念 1.堆是一个完全二叉树 2.小堆(任何一个父亲<孩子),大堆(任何一个父亲>孩子) 堆的结构 物理结构:数组 逻辑结构:二叉树 #pragma once #include<assert.h> #include<iostream> typedef int HPDataType; typedef struct Heap {HPDataType* _a;int…...

CSS中三栏布局的实现

三栏布局一般指的是页面中一共有三栏&#xff0c;左右两栏宽度固定&#xff0c;中间自适应的布局&#xff0c;三栏布局的具体实现&#xff1a; 利用绝对定位&#xff0c;左右两栏设置为绝对定位&#xff0c;中间设置对应方向大小的margin的值。 .outer {position: relative;h…...

Linux搭建我的世界(MC)整合包服务器,All the Mods 9(ATM9)整合包开服教程

Linux使用MCSM面板搭建我的世界(Minecraft)整合包服务器&#xff0c;MC开服教程&#xff0c;All the Mods 9(ATM9)整合包搭建服务器的教程。 本教程使用Docker来运行mc服&#xff0c;可以方便切换不同Java版本&#xff0c;方便安装多个mc服版本。 视频教程&#xff1a;https:…...

让数据在业务间高效流转,镜舟科技与NineData完成产品兼容互认

近日&#xff0c;镜舟科技与NineData完成产品兼容测试。在经过联合测试后&#xff0c;镜舟科技旗下产品与NineData云原生智能数据管理平台完全兼容&#xff0c;整体运行高效稳定。 镜舟科技致力于帮助中国企业构建卓越的数据分析系统&#xff0c;打造独具竞争力的“数据护城河”…...

2.1HTML5基本结构

HTML5实际上不算是一种编程语言&#xff0c;而是一种标记语言。HTML5文件是由一系列成对出现的元素标签嵌套组合而成&#xff0c;这些标签以<元素名>的形式出现&#xff0c;用于标记文本内容的含义。浏览器通过元素标签解析文本内容并将结果显示在网页上&#xff0c;而元…...

设置浏览器显示小于12px以下字体

问题 我们在项目开发过程中有时候会遇到设计师给的小于12px的字体&#xff0c;IE、火狐浏览器、移动端等小于12px的字号大小还是可以正常显示的&#xff0c;但是谷歌浏览器上显示字体最小为12px&#xff0c;css设置font-size&#xff1a;10px&#xff0c;运行代码显示结果仍然…...

web蓝桥杯真题:成语学习

代码&#xff1a; //TODO 点击文字后&#xff0c;在idiom从左到右第一个空的位置加上改文字 getSingleWord(val) {let index this.idiom.indexOf() //从左往右查询空字符串this.$set(this.idiom, index, val) //响应式更新 },// TODO 校验成语是否输入正确答案 confirm…...

外包干了5天,技术明显退步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...

Vue:自定义消息通知组件

一、效果描述 在JS中使用一个Message函数&#xff0c;弹出一个自定义的消息框。 效果体验&#xff1a;缓若江海凝清光 二、实现方式 1.新建一个消息组件 2.新建一个js文件&#xff0c;新建一个需要导出函数 3.在函数中新建一个Vue实例&#xff0c;并将消息组件挂载上去。…...

2023 收入最高的十大编程语言

本期共享的是 —— 地球上目前已知超过 200 种可用的编程语言&#xff0c;了解哪些语言在 2023 为开发者提供更高的薪水至关重要。 过去一年里&#xff0c;我分析了来自地球各地超过 1000 万个开发职位空缺&#xff0c;辅助我们了解市场&#xff0c;以及人气最高和收入最高的语…...

Github 2024-03-11 开源项目周报 Top15

根据Github Trendings的统计&#xff0c;本周(2024-03-11统计)共有15个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目3Jupyter Notebook项目3C#项目1HTML项目1CSS项目1Dart项目1Lua项目1Shell项目1Rust…...

【DAY10 软考中级备考笔记】数据结构 图

数据结构 图 3月11日 – 天气&#xff1a;晴 晚上无线网络突然不能用了&#xff0c;花费好久弄这个&#xff0c;耽误了一些时间 1. 图的定义 这里需要注意完全图的定义&#xff0c;以及完全图的边数 这里需要注意连通图和连通分量的概念。 2. 图的存储结构 图有两种存储结构&a…...

java-ssm-jsp基于java的餐厅点餐系统的设计与实现

java-ssm-jsp基于java的餐厅点餐系统的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全...

蓝桥杯(1):python排序

1 基础 1.1 输出 1.1.1 去掉输出的空格 print("Hello","World",123,sep"") print("hello",world,123,sep) print(hello,world,123) #输出结果 #HelloWorld123 #helloworld123 #hello world 123 1.1.2 以不同的方式结尾 print(&quo…...

SpringMVC请求、响应和拦截器的使用

SpringMVC请求 RequestMapping注解 RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系 RequestMapping注解可以作用在方法和类上 1. 作用在类上&#xff1a;第一级的访问目录 2. 作用在方法上&#xff1a;第二级的访问目录 3. 细节&#xff1a;路径可以不编写…...

基于springboot+layui仓库管理系统设计和实现

基于 java springbootlayui仓库管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…...

【开源-土拨鼠充电系统】鸿蒙 HarmonyOS 4.0+微信小程序+云平台

本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/cheinlu/groundhog-charging-system ✍Gitee开源项目地址&#x1f449;&#xff1a;https://gitee.com/cheinlu/groundhog-charging-system ✨踩坑不易&am…...

[抽象]工厂模式([Abstract] Factory)——创建型模式

[抽象]工厂模式——创建型模式 什么是抽象工厂&#xff1f; 抽象工厂模式是一种创建型设计模式&#xff0c;让你能够保证在客户端程序中创建一系列有依赖的对象组时&#xff0c;无需关心这些对象的类型。 具体来说&#xff1a; 对象的创建与使用分离&#xff1a; 抽象工厂模…...

QT网络编程之实现UDP广播发送和接收

推荐一个不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;内容全面&#xff0c;作为入门科普和学习提升都不错&#xff0c;分享一下给大家&#xff1a;前言https://www.captainbed.cn/ai 一.UDP通信 1.QT中实现UDP通信主要用到了以下类&#xff1a;QUdpSocket、QHost…...

SSL VPN基础原理

目录 SSL ---安全传输协议&#xff08;安全套接层&#xff09;---TLS ----传输层安全协议 SSL的工作原理 SSL会话建立的过程 ​编辑 数据传输过程中的封装示意图 无客户端认证的过程 有客户端认证的过程 SSL VPN的核心技术---虚拟网关技术 服务器验证的点&#xff1a; 资源…...

深入理解FTP协议:文件传输的桥梁

深入理解FTP协议&#xff1a;文件传输的桥梁 在数字化时代&#xff0c;文件传输协议&#xff08;FTP&#xff09;是互联网上进行文件交换的重要手段。FTP允许用户在不同的计算机之间传输文件&#xff0c;无论是上传还是下载&#xff0c;都提供了一种稳定且高效的方式。本文将深…...