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

Java监听器与观察者模式

Java监听器与观察者模式

Java中的监听器(Listener)和观察者模式(Observer Pattern)都是用于处理对象间的事件通知和响应的设计模式。它们的目的是在对象之间建立一种松散的耦合,使得一个对象的状态变化可以通知到其他对象,并且其他对象能够相应地作出变化。
首先我们先用两个实例来感受一下:

观察者模式:

观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
在这里插入图片描述

在Java中,观察者模式通常使用java.util.Observable类和java.util.Observer接口来实现。被观察的对象继承Observable类,而观察者实现Observer接口。当被观察对象的状态发生改变时,它会调用notifyObservers()方法,通知所有注册的观察者。

import java.util.Observable;
import java.util.Observer;
// 被观察的对象
class MyObservable extends Observable {private int data;public int getData() {return data;}public void setData(int data) {this.data = data;setChanged(); // 表示状态已改变notifyObservers(data); // 通知观察者}
}// 观察者
class MyObserver implements Observer {@Overridepublic void update(Observable o, Object arg) {if (o instanceof MyObservable) {System.out.println("Data changed to: " + arg);}}
}public class ObserverPatternExample {public static void main(String[] args) {MyObservable observable = new MyObservable();MyObserver observer = new MyObserver();observable.addObserver(observer);observable.setData(42); // 触发通知}
}

这个代码比较简单,在被观察对象 MyObservable发生改变时,会通知观察者,监听此对象的观察者 MyObserver会同步做出处理。
其中有一步observable.addObserver(observer); 这个是将被观察对象让观察者检测到
其内部实现主要在Observable
源码如下所示

public class Observable {private boolean changed = false;private Vector<Observer> obs = new Vector();  //观察者列表public Observable() {}public synchronized void addObserver(Observer o) {  //添加观察者if (o == null) {throw new NullPointerException();} else {if (!this.obs.contains(o)) {this.obs.addElement(o);}}}public synchronized void deleteObserver(Observer o) {  //删除观察者this.obs.removeElement(o);}public void notifyObservers() {   //通知观察者this.notifyObservers((Object)null);}public void notifyObservers(Object arg) { //通知观察者带参执行Object[] arrLocal;synchronized(this) {if (!this.changed) {return;}arrLocal = this.obs.toArray();this.clearChanged();}for(int i = arrLocal.length - 1; i >= 0; --i) {((Observer)arrLocal[i]).update(this, arg);}}public synchronized void deleteObservers() { //删除所有观察者this.obs.removeAllElements();}protected synchronized void setChanged() {/当改变是可以通知观察者执行this.changed = true;}protected synchronized void clearChanged() {//当改变是可以通知观察者不执行this.changed = false;}public synchronized boolean hasChanged() { //获取观察者是否可以执行return this.changed;}public synchronized int countObservers() {//返回当前观察者个数return this.obs.size();}
}

通过源码可以看出addObserver方法可以将观察者加入到这个被观察者的属性中,通过维护一个Vector来维护所有的观察者,观察者实现Observer接口的update方法,来执行通知的方法。

监听器模式:

监听器模式并不是一个新的设计模式,它是观察者模式在特定场景下的一种改造和应用。通常,观察者模式的主题在通知观察者时,通知中不包含任何信息。如果这个过程中携带了一些其他信息,那么主题本身就成为了事件源,而携带信息的封装类就成为了事件。此时的观察者模式,也就升级为监听器了。监听器模式是观察者模式的另一种形态。
监听器模式通常包含三个角色:事件源、事件对象、事件监听器。

在Java中,监听器模式通常通过接口和事件对象来实现。
具体实现如下:


// 监听器接口
interface MyListener {void onDataChanged(int newData);
}
// 发布者类
class EventSource {private MyListener listener;public void setListener(MyListener listener) {this.listener = listener;}public void fireEvent(int newData) {if (listener != null) {listener.onDataChanged(newData);}}
}// 订阅者类
class MySubscriber implements MyListener {@Overridepublic void onDataChanged(int newData) {System.out.println("Data changed to: " + newData);}
}public class ListenerPatternExample {public static void main(String[] args) {EventSource eventSource = new EventSource();MySubscriber subscriber = new MySubscriber();eventSource.setListener(subscriber);eventSource.fireEvent(42); // 触发事件}
}

相关文章:

  • 如何不用手机号获取自己的opeai中的key
  • ROS2 学习08 导航Nav2:简介、安装、测试效果、错误处理
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • JAVA 版多商家入驻 直播带货 商城系统 B2B2C 之 鸿鹄云商B2B2C产品概述
  • 我的网站服务器被入侵了该怎么办?
  • Word Excel模版引擎
  • 智能部署之巅:Amazon SageMaker引领机器学习革新
  • 【FPGA】Quartus18.1打包封装网表文件(.qxp)详细教程
  • 仪器器材企业网站搭建的作用是什么
  • 测试用例设计方法六脉神剑——第四剑:石破天惊,功能图法攻阵
  • 智能优化算法应用:基于鸽群算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • 自定义Axure元件库及原型图泳道图的绘制(详细不同类的案例)
  • Springboot整合Redis实现消息发布订阅
  • 做数据分析为何要学统计学(2)——如何估计总体概率分布
  • 我们一起做过的SPA——Nuxt.js介绍
  • @jsonView过滤属性
  • angular组件开发
  • PHP面试之三:MySQL数据库
  • PHP那些事儿
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • vue2.0项目引入element-ui
  • WePY 在小程序性能调优上做出的探究
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 京东美团研发面经
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 理清楚Vue的结构
  • 聊聊sentinel的DegradeSlot
  • 网络应用优化——时延与带宽
  • 微信小程序开发问题汇总
  • 问题之ssh中Host key verification failed的解决
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • ![CDATA[ ]] 是什么东东
  • # 安徽锐锋科技IDMS系统简介
  • ###STL(标准模板库)
  • #pragma 指令
  • #控制台大学课堂点名问题_课堂随机点名
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (solr系列:一)使用tomcat部署solr服务
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (力扣)1314.矩阵区域和
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)scrum常见工具列表
  • (转载)hibernate缓存
  • .FileZilla的使用和主动模式被动模式介绍
  • .gitignore文件_Git:.gitignore
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET CORE Aws S3 使用
  • .NET 依赖注入和配置系统