对于观察者模式,其实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-; i>=; 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();
}
}

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

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

Observable:

 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方法,通知所有观察者
}
}
Observer:
 public class Subscribe implements Observer {

     public Subscribe(Observable o) {
//将该观察者放入待通知观察者里
o.addObserver(this);
} @Override
public void update(Observable o, Object arg) {
System.out.println("收到了消息:" + ((Publish)o).getData());
}
}

测试:

 public class ObserverTest {

     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通过接口实现匿名类的实例

    package com.chase.test; /** * 通过接口实现匿名类的实例 * * @author Chase * * @date 2013-10-18 下午04:28:17 * * @ve ...

  4. java List接口中常用类

    Vector:线程安全,但速度慢,已被ArrayList替代. ArrayList:线程不安全,查询速度快. LinkedList:链表结构,增删速度快.取出List集合中元素的方式: get(int ...

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

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

  6. 观察者设计模式( Observable类Observer接口)

    如果要想实现观察者模式,则必须依靠Java.util包中提供的Observable类和Observer接口. class House extends Observable{ // 表示房子可以被观察  ...

  7. [Android&Java]浅谈设计模式-代码篇:观察者模式Observer

    观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...

  8. Java 设计模式系列(十五)观察者模式(Observer)

    Java 设计模式系列(十五)观察者模式(Observer) Java 设计模式系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Java ...

  9. java源码阅读Observable(观察者模式)

    1类签名和简介 package java.util; public class Observable Observable是Java内置的观察者模式中的主题类(没错,是类不是接口),和其对应的观察者接 ...

随机推荐

  1. Egret 获取不到皮肤中的按钮 id

    最近Egret开发中遇到的Q,Egret 获取不到皮肤中的按钮 id,也就没法针对按钮进行监听和执行对应操作: 问题的关键就是,exml获取应该出现了差错: 经过查询我发现this.skinName的 ...

  2. 转 What is Redis and what do I use it for?

    原文: http://stackoverflow.com/questions/7888880/what-is-redis-and-what-do-i-use-it-for Redis = Remote ...

  3. FIlter(2)—案例

    案例 demo2,login.jsp请求提交到hello.jsp,该页面中有两个text,分别使用两个Filter链拦截,验证账号密码是否正确,把账号密码设置到Filter初始化参数中 login.j ...

  4. hdu1003 Max Sum(最大子串)

    https://vjudge.net/problem/HDU-1003 注意考虑如果全为负的情况,特判. 还有输出格式,最后一个输出不用再空行. #include<iostream> #i ...

  5. Deepin 15.4 破解安装 SecureFX-7.3 失败

    参考先前的文章(Ubuntu 14 安装并破解SSH工具 SecureCRT),破解安装 SecureCRT-7.3  成功,但是破解安装 SecureFX-7.3 时就一直报错: Insuffici ...

  6. javaScript系列 [03]-javaScript原型对象

    [03]-javaScript原型对象 引用: javaScript是一门基于原型的语言,它允许对象通过原型链引用另一个对象来构建对象中的复杂性,JavaScript使用原型链这种机制来实现动态代理. ...

  7. eclipse实现代码块折叠-类似于VS中的#region……#endregion

    背 景 刚才在写代码的时候,写了十几行可以说是重复的代码: 如果整个方法或类中代码多了,感觉它们太TM占地方了,给读者在阅读代码上造成很大的困难,于是想到能不能把他们“浓缩”成一行,脑子里第一个闪现出 ...

  8. 【转】Selenium - 封装WebDrivers (C#)

    本文转载自:http://www.cnblogs.com/qixue/p/3977135.html Web element仍然使用OpenQA.Selenium.IWebElement, 本类库将Se ...

  9. update使用inner join

    一.update 基础语法 UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 上面是我们常见的更新表的方式,其实我们还可以去另外一张表的数据来更新当前的表数据,如现在就有这 ...

  10. Tomcat 9.0 安装配置

    本文转自:http://blog.sina.com.cn/s/blog_15126e2170102w5o8.html 一.JDK的安装与配置 1.从官网下载jdk,注意是jdk不是jre.最好从官网下 ...