java observable类,利用Java提供的Observer接口和Observable类实现观察者模式

对于观察者模式,其实Java已经为我们提供了已有的接口和类。对于订阅者(Subscribe,观察者)Java为我们提供了一个接口,JDK源码如下:

package java.util;

public interface Observer {

void update(Observable o, Object arg);

}

和我们上一篇实现的观察者一样,仅提供一个update方法用于接收通知者的通知做出相应改变。

我们再来看看Java为我们提供了一个怎样的通知者(Publish,发布者),JDK源码如下:

package java.util;

public class Observable {

private boolean changed = false;  //是否改变状态

private Vector obs;    //Vector利用同步方法来线程安全,线程安全在多线程情况下不会造成数据混乱

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();  //将Vector转换成数组

clearChanged();    //重置状态

}

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();

}

}

不得不说,Java源码考虑得就是比自己写的要好。首先,使用Vector,Vector相比于ArrayList来说,它是线程安全的。其次,在添加和删除观察者时对两个方法使用了synchronized关键字,这都是在为多线程考虑。确实Java源码并不是那么可怕,它同样也是由一些最简单最基础的组合而来。

接下来我们来看看是如何利用Java提供的接口和方法来实现观察者模式。

package day_10_observer_jdk;

import java.util.Observable;

import java.util.Observer;

/**

* 实现java.util.Observer接口的观察者

* @author turbo

*

* 2016年9月14日

*/

public class Subscribe implements Observer {

public Subscribe(Observable o){

o.addObserver(this); //将该观察者放入待通知观察者里

}

/* (non-Javadoc)

* @see java.util.Observer#update(java.util.Observable, java.lang.Object)

*/

@Override

public void update(Observable o, Object arg) {

System.out.println("收到通知:" + ((Publish)o).getData());

}

}

package day_10_observer_jdk;

import java.util.Observable;

/**

* 继承java.util.Observable的通知者

* @author turbo

*

* 2016年9月14日

*/

public class Publish extends Observable {

private String data = "";

public String getData() {

return data;

}

public void setData(String data) {

if (!this.data.equals(data)){

this.data = data;

setChanged(); //改变通知者的状态

}

notifyObservers(); //调用父类Observable方法,通知所有观察者

}

}

客户端测试代码:

package day_10_observer_jdk;

/**

* @author turbo

*

* 2016年9月14日

*/

public class Main {

/**

* @param args

*/

public static void main(String[] args) {

Publish publish = new Publish();

Subscribe subscribe = new Subscribe(publish);

publish.setData("开始");

}

}

这样我们就利用了Java给我们提供的Observer接口和Observable类实现了观察者模式。上一篇我们提到了事件委托,我们在下一篇来了解一下什么是事件委托。

Java Observer接口和Observable类实现观察者模式

对于观察者模式,其实Java已经为我们提供了已有的接口和类.对于订阅者(Subscribe,观察者)Java为我们提供了一个接口,JDK源码如下: package java.util; public ...

Java中使用Observer接口和Observable类实践Observer观察者模式

在Java中通过Observable类和Observer接口实现了观察者模式.实现Observer接口的对象是观察者,继承Observable的对象是被观察者. 1. 实现观察者模式 实现观察者模式非 ...

利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)

最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...

利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包括增删改查、JavaBean反射原理,附源代码)

近期看老罗的视频,跟着完毕了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完毕对数据库的增删改查.当中查询这块,包含普通的查询和利用反射完毕的查询,主要包含以下几个函数接口 ...

Java常用类库--观察者设计模式( Observable类Observer接口)

如果要想实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口. import java.util.* ; class House extends Obse ...

利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

java学习——JDK1.8接口和实现类

Java 8 新特性:接口的静态方法和默认方法 https://blog.csdn.net/sun_promise/article/details/51220518 接口的默认方法和静态方法 http ...

Java学习笔记_22_Set接口的实现类

22.Set接口的实现类: Set接口存放的元素是无序的且不包括反复元素. 1>实现类HashSet: HashSet类依据元素的哈希码进行存放,取出时也能够依据哈希码高速找到.HashSet不 ...

Java并发编程:Future接口、FutureTask类

在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就 ...

随机推荐

Spring MVC静态资源处理(转)

优雅REST风格的资源URL不希望带 .html 或 .do 等后缀.由于早期的Spring MVC不能很好地处理静态资源,所以在web.xml中配置DispatcherServlet的请求映射,往往 ...

MySql运算符

算数运算符 加(+).减(-).乘(*).除(/).求余(%) 比较运算符 大于(>).小于(=).小于等于(<=).不等于(!= 或者 < ...

const常量折叠

首先来看一个例子: int main(int argc, char* argv[]) { ; int *j = (int *) &i; *j=; cout<

单片机串口通讯RXD与TXD如何对接详解

相信很多人都对单片机与计算机或者芯片通信时,RXD与TXD如何连接比较困惑.因为在一些电路图中,有的是直连接法,有的是交叉接法,让人有点摸不着头脑. 首先需要明白两个概念,就是DTE和DCE.DTE是 ...

Android的读写文件权限

设置文件生成的权限: public static boolean saveInfo( Context context, String userName, String userPass, int mo ...

Eclipse rap 富客户端开发总结&lpar;15&rpar; :rap如何使用js

1. 把输入的字符串当 javascript 执行 try { RWT.getResponse().getWriter().println("alert('123');"); }  ...

tornado超时机制

1.https://blog.lzhaohao.info/archive/build-a-comet-application-using-tornado-and-nginx/ 2.http://qin ...

Entry的验证

Entry组件是支持验证输入的合法性的, 比如要求输入数字,你输入了字母就是非法. 实现该功能,需要通过设置validate,validatecommand,invalidcommand选项. 1.首 ...

9、Qt Project之简单的数据库接口

简单的数据库接口  Step1:首先完成整个UI界面的额设计: <?xml version="1.0" encoding="UTF-8"?> &lt ...

hdu5443 ST表裸题:求区间最大

#include #include #include #include #d ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值