对于观察者模式,其实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. Python特色数据类型(列表)(上)

    Python从零开始系列连载(9)——Python特色数据类型(列表)(上) 原创 2017-10-07 王大伟 Python爱好者社区 列表 列表,可以是这样的: 分享了一波我的网易云音乐列表 今天 ...

  2. [jzoj]3521.道路覆盖(cover)

    Link https://jzoj.net/senior/#main/show/3521 Description Tar把一段凹凸不平的路分成了高度不同的N段,并用H[i]表示第i段高度.现在Tar一 ...

  3. Flask 三方组件 Flask-Session

    使用 from flask import session, Flask from flask_session import Session from redis import Redis app = ...

  4. 初识hibernate——环境搭建

    一  配置过程 1. 创建一个项目 2. 导包    required里的包 optional里的c3p0连接池的三个包 数据库驱动包 Junit 3.创建Hibernate的配置文件(hiberna ...

  5. sqli-labs Less-11 and Less-12

    这关是post注入的世界,post注入就是表单中填好数据通常会被送到服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理). 不显示东西,那么加引号等 ...

  6. jQuery 学习04——遍历:定义、向上、向下、同级、过滤

    Query 遍历,意为"移动",用于根据其相对于其他元素的关系来"查找"(或选取)HTML 元素. 以某项选择开始,并沿着这个选择移动,直到抵达您期望的元素为止 ...

  7. delphi 设置多屏幕

    //poScreenCenter时,窗体会显示到主显示器的中央 MainForm.Position := poScreenCenter; function TGAEAMainForm.GetWorkA ...

  8. Js实现Table动态添加一行的小例子

    <form id="form1" runat="server"> <div> <table id=" style=&qu ...

  9. Google Maps V3 之 路线服务

    概述 您可以使用 DirectionsService 对象计算路线(使用各种交通方式).此对象与 Google Maps API 路线服务进行通信,该服务会接收路线请求并返回计算的结果.您可以自行处理 ...

  10. JS 之 阻止事件冒泡,阻止默认事件,event.stopPropagation()和event.preventDefault(),return false的区别

    在前端开发中,有时我们需要阻止冒泡和阻止默认事件的发生. 一.event.stopPropagation() 阻止事件的冒泡,不让事件向documen上蔓延,但是默认事件任然会执行,当调用这个方法的时 ...