对于观察者模式,其实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类实现观察者模式的更多相关文章

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

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

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

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

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

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

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

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

  5. java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】

    Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 第1章1zabbix快速入门

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; t ...

  2. Mesos+Zookeeper+Marathon+Docker分布式集群管理最佳实践

    参考赵班长的unixhot以及马亮blog 笔者QQ:572891887 Linux架构交流群:471443208 1.1Mesos简介 Mesos是Apache下的开源分布式资源管理框架,它被称为分 ...

  3. 手机自动化测试:appium源码分析之bootstrap十七

    手机自动化测试:appium源码分析之bootstrap十七   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  4. 微信小程序首页总结

      效果图如下 首先从大的方面来讲,就是设置了window的属性 "navigationBarBackgroundColor": "#AFE2E6",//bar ...

  5. jQ层级选择器

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  6. 【Java进阶】——初识数据库连接池

    [简介] 数据库连接池:程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的链接进行申请,使用,释放. 相比之前的程序连接,减少了数据库的打开关闭次数,从而减少了程序响应的 ...

  7. Hibernate基础学习(五)—对象-关系映射(下)

    一.单向n-1 单向n-1关联只需从n的一端可以访问1的一端. 域模型: 从Order到Customer的多对一单向关联.Order类中定义一个Customer属性,而在Customer类不用存放Or ...

  8. JavaWeb总结(七)—JSTL标签库

    一.JSTL标签库介绍 JSTL标签库的使用时为了弥补HTML标签的不足,规范自定义标签的使用而诞生的.使用JSTL标签的目的是不希望在JSP中出现Java逻辑代码. 二.JSTL标签库的分类 1.核 ...

  9. 实现高效的GPRS驱动程序

    1. 引言 用过几款GPRS模块,也从淘宝上买过多个GPRS模块,一般的都会送一个驱动程序和使用demo,但是代码质量都较低. 回头看了下几年前使用的GPRS代码,从今天的角度来看,也就是买模块赠送一 ...

  10. Python爬虫入门 Urllib库的基本使用

    1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...