java与模式观察者模式_谈谈java中的观察者模式
图片.png
前言
了解设计模式的童鞋应该都知道观察者模式,类似于上图的结构,其中Observer作为观察者,Observable则作为被观察者,Observable的状态改变会给注册的Observer进行通知,考虑易用和低耦合,保证高度的协作。
Demo展示
我们首先来看一下demo,也就是上图类图中所展示的程序,MyObservable非常简单,只是继承了Observable:
public class MyObservable extends Observable{
public static void main(String[] args) {
MyObservable myObservable = new MyObservable();
myObservable.addObserver(new MyObserver());
myObservable.setChanged();
myObservable.notifyObservers("aaa");
}
}
此处为了简化结构,直接将main方法写在MyObservable中用于进行效果的测试,main中我们先实例化了MyObservable类,并且将一个MyObserver实例用addObserver方法加入它的观察者列表中,然后通过setChanged改变changed的状态值,随后便可以notifyObservers,里面可以带参数做消息传递,也可以不带参数。关于changed,是因为只有该变量为true的情况下,才会进行通知,否则notifyObservers是无法通知到具体Observer的。
MyObserver的结构也非常简单,由于继承了Observer接口,因此需要实现它的抽象方法update,这个方法也是用于接收Observable发来的通知并执行相应的处理逻辑的:
public class MyObserver implements Observer{
public void update(Observable o, Object arg) {
System.out.println("观察对象为:" + o + ";传递参数为:" + arg);
}
}
运行一下demo,可以看到结果为:
观察对象为:com.sunny.MyObservable@60e53b93;传递参数为:aaa
而在注释了setChanged方法之后,会发现没有任何输出,可以理解为,并没有真正通知到Observer。
原理解析
原理非常简单,查看Observable源码即可。其实从类图中就可以看出一些端倪,Observable中只有两个变量,一个是changed,一个是obs,从之前的分析可以看出changed只是一个状态指示的变量,那么obs应该就是一个用于存储Observer实例的变量了,它具体是用一个Vector来进行存储的。
private boolean changed = false;
private Vector obs;
这样的情况下,我们很容易就可以猜测,obs的初始化应该是在Observable的构造方法中实现的,果不其然,构造方法也仅仅只是完成了obs的初始化:
public Observable() {
obs = new Vector<>();
}
然后我们更为关心的是Observable与Observer之间的关系,那么就是重点关注两个方法,addObserver和notifyObservers。addObserver很显然,里面的主要操作是将作为参数传入的Observer加入到Vector中:
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
notifyObservers则是逐一通知Observer的过程,不过在这个方法中会检查changed的值,以及会在通知完成后对changed归零(其中clearChanged方法就是将changed变量重新置为false):
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
到这里基本上整个基于jdk实现的观察者模式的原理已经非常明了了,另外值得注意的一个点是,这个实现中用了一些措施来使它线程安全。比如,使用线程安全的容器Vector,addObserver方法进行了枷锁,在notifyObservers方法中,有一个操作进行了加锁:
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
这里主要确保了对changed变量的验证和清零操作以及将obs中的元素赋值给arrLocal的过程是原子操作,这里减少了锁的粒度,提高并发性,也因此大家能明白为何需要arrLocal这个变量了,随后对arrLocal数组进行便利并逐一通知则不需要加锁了,因为arrLocal已经是一个本地变量,并未暴露。
综上,就是基于jdk实现观察者模式的主要原理了。
欢迎小伙伴与我讨论哦~
java与模式观察者模式_谈谈java中的观察者模式相关推荐
- java timmer模式配置_使用java配置定时任务的几种配置方式及示例
Spring定时器,主要有两种实现方式,包括Java Timer定时和Quartz定时器! 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 package ...
- java.lang.IllegalArgumentException: 字符[_]在域名中永远无效。 at
[http-nio-8080-exec-1] org.apache.coyote.AbstractProcessor.parseHost [xxx_tomcat] 是无效主机注意:更多的请求解析错误将 ...
- java项目----教务管理系统_基于Java的教务管理系统
java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...
- java观察者模式在spring中的应用_在Spring中使用观察者模式
菜鸟教程中关于观察者模式的介绍如下: 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而 ...
- java 观察者模式_图解Java设计模式之观察者模式
图解Java设计模式之观察者模式 天气预报项目需求 天气预报设计方案 1 - 普通方案 观察者模式(Observer)原理 观察者模式解决天气预报需求 观察者模式在JDK应用的源码分析 天气预报项目需 ...
- java多核并行计算_谈谈Java任务的并行处理
前言 谈到并行,我们可能最先想到的是线程,多个线程一起运行,来提高我们系统的整体处理速度:为什么使用多个线程就能提高处理速度,因为现在计算机普遍都是多核处理器,我们需要充分利用cpu资源:如果站的更高 ...
- java stream 求和_谈谈Java任务的并行处理
作者:ksfzhaohui 前言 谈到并行,我们可能最先想到的是线程,多个线程一起运行,来提高我们系统的整体处理速度:为什么使用多个线程就能提高处理速度,因为现在计算机普遍都是多核处理器,我们需要充分 ...
- java web.xml 监听器_【JAVA 核心技术】java web 中的监听器
为什么要有监听器? 监听器是用来处理一系列事件的java类,可被配置在java web项目中. 既然如此,为什么不用代码直接调用监听器? 这可能是因为J2EE规范规定的项目工程标准,用web.xml指 ...
- java使用外部库_在Java中使用外部库
java使用外部库 Java附带了一组核心库,其中包括定义常用数据类型和相关行为的库,例如String或Date : 与主机操作系统进行交互的实用程序,例如System或File : 有用的子系统来管 ...
- java与模式孙悟空_悟空模式-java-工厂方法模式
[却说那七衣仙女自受了大圣的定身法术,一周天方能解脱,各提花篮,回奏王母说道:"齐天大圣使术法困住我等,故此来迟."王母问道:"汝等摘了多少蟠桃?"仙女道:&q ...
最新文章
- 利用TCMalloc替换Nginx和Redis默认glibc库的malloc内存分配
- 从键盘输入一个正整数(不多于5位),计算该正整数与789之和(记为sum)
- Jass 技能模型定义(转)
- 不装mono,你的.NET程序照样可以在Linux上运行
- java 去掉 t_关于Java:在LocalDateTime中不能删除“ T”
- 华为云EI人脸识别接口初探
- 饮冰三年-人工智能-Python-27 Django Form组件
- twaver html5,twaver-html5-1.5.9---2D
- 满满的提高芝麻分实操技巧!
- KATEX公式编辑器符号大全-CSDN的Mardown公式支持
- 鸡小德手机小常识 如何鉴定手机是否为行货
- Flutter 3更新详解
- 【交互设计师必备书单】资深交互设计师推荐的交互设计师必看的七本书
- python pip安装numpy_【风马一族_Python】 安装pip与Numpy
- oracle 数据库如何获取一条sql语句执行所消耗耗费的时间?
- 解决VS在Release下编译程序报“应用程序无法启动,应用程序的并行配置不正确”的问题
- 思维升级-如何设计一个秒杀系统?
- 2022年广电行业研究报告
- C++黑客编程:键盘记录器,HOOK技术实现
- Linux下的cmt2300a驱动
热门文章
- trycatch抛出异常_满屏的trycatch,这代码写得真丑!
- bio和bieos哪个标注模式好_通用块层bio详解
- cpu顶盖怎么看步进_拆解报告|360AI音箱,深度硬件解析,带你看懂360智能音箱内部...
- JavaScript:判断两个日期之间的差距天数
- HighCharts:设置坐标轴字体样式
- Git:git commit后撤销commit 提交
- 实战爬虫:python爬虫之爬取虎扑湖人专区新闻中科比相关新闻
- 论文笔记_S2D.71_2020_CVPR_用于自监督单目深度估计的3D packing
- Ubuntu安装Tensorflow及anaconda环境下使用TensorFlow
- mysql 数据库授权