观察者模式--java jdk中提供的支持
一、简介
观察者设计模式有如下四个角色
- 抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现,也可以使用非抽象类来实现。
- 具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
- 抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
- 具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。通常用一个子类实现。
观察者设计模式类图如下:
二、java JDK中对观察者的支持
java JDK中提供了Observer 与 Observable两个类。Observer类可以看作是抽象观察者角色,而Observable是抽象主题角色。
1、Objserver
Objserver 是个接口,代码如下:
public interface Observer {/*** 该方法当主题对象发生改变的时候被调用. An* 一个应用调用主题对象的notifyObservers方法来application calls an <tt>Observable</tt> object's* <code>notifyObservers</code> method to have all the object's* observers notified of the change.** @param o the observable object.* @param arg an argument passed to the <code>notifyObservers</code>* method.*/void update(Observable o, Object arg); }
它只提供了一个update,让子类去实现。当主题对象发生改变的时候,就会调用观察者对象的update方法,从而达到观察者发生改变的目的。
2、Observable
Observable是个类,代码如下:
public class Observable {private boolean changed = false;private Vector obs;//用于存放观察者对象的引用public Observable() {obs = new Vector();} //添加一个观察者public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}} //移除一个观察者public synchronized void deleteObserver(Observer o) {obs.removeElement(o);} //通知所有观察者public void notifyObservers() {notifyObservers(null);}//通知指定的观察者public void notifyObservers(Object arg) { Object[] arrLocal;synchronized (this) { if (!changed)//当状态没有发生改变的时候,直接返回return;arrLocal = obs.toArray();clearChanged();}//通知并调用观察者的update方法for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);} //移除所有观察者public synchronized void deleteObservers() {obs.removeAllElements();} //设置状态改变protected synchronized void setChanged() {changed = true;} //重置状态protected synchronized void clearChanged() {changed = false;}//判断是否状态是否发生改变public synchronized boolean hasChanged() {return changed;}返回观察者的个数public synchronized int countObservers() {return obs.size();} }
从代码可以看出,我们可以让具体主题对象继承Observable类,具体观察者对象实现Observer接口并实现update方法。调用的时候只需要实例化具体主题对象与具体观察者对象,然后将具体观察者对象添加到具体主题对象中的obs(Vector)列表。当具体主题对象的状态发生该变时,调用观察者对象的update方法(这里状态发生该变指的是调用主题对象的某个方法,该方法里面有对具体观察者对象的update方法的调用)。
三、实例
具体观察者对象
具体主题对象 package com.observer;import java.util.Observable; /*** 具体主题对象**/ public class ConcreteSubject extends Observable {private String info;public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public void doSomething(String str) {System.out.println("subject: " + str);setInfo(str);setChanged();//改变主题对象的状态,这里如果不改变它的状态,则不会对观察者对象调用update方法 // notifyObservers();//也可以不传递参数notifyObservers("subject is changed");//这里传递的参数是观察者对象中update方法参数列表中的第二个参数 } }
具体观察者对象
package com.observer;import java.util.Observable; import java.util.Observer; /*** 具体观察者对象**/ public class ConcreteObserver implements Observer {/*** @param subject 具体主题对象* @param arg notifyObservers(String str) 传递的参数*/public void update(Observable o, Object arg) {System.out.println(arg);ConcreteSubject subject = (ConcreteSubject)o;System.out.println("observer: " + subject.getInfo());} }
调用代码:
package com.observer;import java.util.Observer;public class Test {public static void main(String[] args) {//观察者对象Observer observer = new ConcreteObserver();Observer observer2 = new ConcreteObserver();Observer observer3 = new ConcreteObserver();//主体对象ConcreteSubject observable = new ConcreteSubject();//观察者加入主题对象汇总的观察者列表 observable.addObserver(observer);observable.addObserver(observer2);observable.addObserver(observer3);//主体对象发生改变observable.doSomething("happy");observable.doSomething("sad");} }
观察者模式--java jdk中提供的支持相关推荐
- JDK中提供的实现——通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例
JDK中提供的实现 在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例. 1 ...
- Java JDK中几个经典的版本
Java JDK中几个经典的版本 1. 1995年05月23日 JDK 1.0 版发布,于1996年JDK正式提供下载,标志着Java的诞生. 2. 1998年12月04日 JDK 1.2 版发布,而 ...
- Java黑皮书课后题第10章:**10.23(实现String类)在Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString2)
**10.23(实现String类)在Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString2) 题目 简短的吐槽 代码:这里将类名改用Test23_MyStrin ...
- java logging包_用JDK中提供的java.util.logging.*包创建Logger对象----原创
由于项目中用到了Applet与Servlet之间(客户端用Applet.Server端用Servlet)的通信,要求: 1:>客户端与服务端必须出Log. 2:>浏览器在加载Applet时 ...
- java ssl证书生成_java – 使用jdk中提供的keytool生成SSL证书
我在Web应用程序中使用的密钥库文件已于上周过期.我很久以前就生成了它.所以我开始使用keytool生成新证书.我使用此证书连接事务服务器和Web服务器.我想为此应用程序使用自签名证书.我使用以下命令 ...
- Java jdk中的部分工具javac javaw javaws javadoc javah javap jar jdb jps的作用
一.JDK 工具和实用程序 JDK提供的标准工具和程序 基本工具:javac, java, javadoc, apt, appletviewer, jar, jdb, javah, javap, ex ...
- jdk中提供的Collection、Collections、Collector、Collectors你分的清楚?
初次一看四个有点相似,而且有些时候一不小心还真有可能敲错,因为喜欢代码提示没仔细看提示,结果通过.去调用结果发现没有找到你想用的方法.所以写代码的时候需要注意一点这个区别 Collections.em ...
- java jdk中的归并排序实现
在Arrays.java中的sort中 public static void sort(Object[] a, int fromIndex, int toIndex) {if (LegacyMerge ...
- Java黑皮书课后题第10章:10.24(实现Character类)在Java库中提供了Character类,给出你自己对这个类的实现(将新类命名为MyCharacter)
代码解释 这里为区分不同题目,类名更改为Test24_MyCharacter.java 破题 这里的"破"和之前写的不太一样,不是动词,不是解决问题的意思 而是形容词 很明显这道题 ...
最新文章
- python实现 “不带中括号”输出列表中的数据
- python函数拟合不规则曲线_python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案...
- Vue.js 使用 Swiper.js 在 iOS 11 时出现错误
- 2021年春季学期-信号与系统-第八次作业参考答案-第六小题
- avalon数据已更新,视图未更新的bug修复
- python编程从入门到实践读书笔记-《Python编程:从入门到实践》项目部分读书笔记(二)...
- 宁波python学习_python学习第十五天
- dict格式转字符串两种方法的区别
- Python学习之函数返回多个值
- 5分钟了解TypeScript
- 100g流量在电脑上可以用多久_三大运营商5G体验方案出炉!100G一个月够不够?...
- redis api 中文文档_我的Redis学习资料库
- Hive 分区表操作 创建、删除
- 基于live555开发嵌入式linux系统的rtsp直播服务
- sqlserver200864位下载_SQL2008下载 SQL Server 2008 R2 简体中文版(64位) 下载-脚本之家
- Windows平台下使用GoLand生成Linux可执行文件
- 谷歌打开微信定位服务器地址,使用Chrome修改user agent模拟微信内置浏览器
- (转)粒子编辑器Particle designer属性的介绍
- python 作用域知识点整理
- Linux错误:bash:finger 未找到命令...
热门文章
- PHP三维数组变一维
- RocketMQ消息存储原理
- ​同样更新分支,git merge 和 rebase 有什么区别?
- 单调栈解决维持相对位置不变最小/最大字典序问题
- JAVA内存模型与线程安全
- ios平台实现局域网ip扫描
- 【跃迁之路】【593天】程序员高效学习方法论探索系列(实验阶段350-2018.09.21)...
- FTP(二)ftp部署与防火墙配置
- Docker 的两类存储资源 - 每天5分钟玩转 Docker 容器技术(38)
- centos 7下Hadoop 2.7.2 伪分布式安装