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-; 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类实现观察者模式的更多相关文章
- 利用Java提供的Observer接口和Observable类实现观察者模式
对于观察者模式,其实Java已经为我们提供了已有的接口和类.对于订阅者(Subscribe,观察者)Java为我们提供了一个接口,JDK源码如下: package java.util; public ...
- Java中使用Observer接口和Observable类实践Observer观察者模式
在Java中通过Observable类和Observer接口实现了观察者模式.实现Observer接口的对象是观察者,继承Observable的对象是被观察者. 1. 实现观察者模式 实现观察者模式非 ...
- Java通过接口实现匿名类的实例
package com.chase.test; /** * 通过接口实现匿名类的实例 * * @author Chase * * @date 2013-10-18 下午04:28:17 * * @ve ...
- java List接口中常用类
Vector:线程安全,但速度慢,已被ArrayList替代. ArrayList:线程不安全,查询速度快. LinkedList:链表结构,增删速度快.取出List集合中元素的方式: get(int ...
- Java常用类库--观察者设计模式( Observable类Observer接口)
如果要想实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口. import java.util.* ; class House extends Obse ...
- 观察者设计模式( Observable类Observer接口)
如果要想实现观察者模式,则必须依靠Java.util包中提供的Observable类和Observer接口. class House extends Observable{ // 表示房子可以被观察 ...
- [Android&Java]浅谈设计模式-代码篇:观察者模式Observer
观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...
- Java 设计模式系列(十五)观察者模式(Observer)
Java 设计模式系列(十五)观察者模式(Observer) Java 设计模式系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Java ...
- java源码阅读Observable(观察者模式)
1类签名和简介 package java.util; public class Observable Observable是Java内置的观察者模式中的主题类(没错,是类不是接口),和其对应的观察者接 ...
随机推荐
- Python特色数据类型(列表)(上)
Python从零开始系列连载(9)——Python特色数据类型(列表)(上) 原创 2017-10-07 王大伟 Python爱好者社区 列表 列表,可以是这样的: 分享了一波我的网易云音乐列表 今天 ...
- [jzoj]3521.道路覆盖(cover)
Link https://jzoj.net/senior/#main/show/3521 Description Tar把一段凹凸不平的路分成了高度不同的N段,并用H[i]表示第i段高度.现在Tar一 ...
- Flask 三方组件 Flask-Session
使用 from flask import session, Flask from flask_session import Session from redis import Redis app = ...
- 初识hibernate——环境搭建
一 配置过程 1. 创建一个项目 2. 导包 required里的包 optional里的c3p0连接池的三个包 数据库驱动包 Junit 3.创建Hibernate的配置文件(hiberna ...
- sqli-labs Less-11 and Less-12
这关是post注入的世界,post注入就是表单中填好数据通常会被送到服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理). 不显示东西,那么加引号等 ...
- jQuery 学习04——遍历:定义、向上、向下、同级、过滤
Query 遍历,意为"移动",用于根据其相对于其他元素的关系来"查找"(或选取)HTML 元素. 以某项选择开始,并沿着这个选择移动,直到抵达您期望的元素为止 ...
- delphi 设置多屏幕
//poScreenCenter时,窗体会显示到主显示器的中央 MainForm.Position := poScreenCenter; function TGAEAMainForm.GetWorkA ...
- Js实现Table动态添加一行的小例子
<form id="form1" runat="server"> <div> <table id=" style=&qu ...
- Google Maps V3 之 路线服务
概述 您可以使用 DirectionsService 对象计算路线(使用各种交通方式).此对象与 Google Maps API 路线服务进行通信,该服务会接收路线请求并返回计算的结果.您可以自行处理 ...
- JS 之 阻止事件冒泡,阻止默认事件,event.stopPropagation()和event.preventDefault(),return false的区别
在前端开发中,有时我们需要阻止冒泡和阻止默认事件的发生. 一.event.stopPropagation() 阻止事件的冒泡,不让事件向documen上蔓延,但是默认事件任然会执行,当调用这个方法的时 ...