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内置的观察者模式中的主题类(没错,是类不是接口),和其对应的观察者接 ...
随机推荐
- Emgucv - 下载、安装、配置
工欲善其事,必先利其器. 一.下载 Emgucv学习之前,我们先要搭建好开发环-Emgucv库.VS开发平台. (1)VS开发平台,个人觉得VS2015挺好用的,比如:自定义窗口布局.更优的代码编辑器 ...
- K Besk [POJ 3111]
描述 Demy有n颗宝石.她的每个珠宝都有一些价值vi和重量wi.自从丈夫约翰在最近的金融危机爆发后,已经决定出售一些珠宝.她决定自己会保留最好的珠宝.她决定保留这样的宝石,使他们的具体价值尽可能大. ...
- 编程菜鸟的日记-初学尝试编程-易传媒笔试题(C++实现)
题目:已知存在两个非递减的有序链表List1和List2,现在需要你将两个链表合并成一个有序的非递增序列链表List3,请用C++编码实现.(所有链表均为单链表结构) 思路:此处链表是否都有表头并没有 ...
- Python Mongodb接口
Python Mongodb接口 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. 同时,MongoDB 是一个介于关系 ...
- Kafka中时间轮分析与Java实现
在Kafka中应用了大量的延迟操作但在Kafka中 并没用使用JDK自带的Timer或是DelayQueue用于延迟操作,而是使用自己开发的DelayedOperationPurgatory组件用于管 ...
- jQuery 学习(2)——jQuery选择器
1.jQuery为元素添加CSS样式如下: <div id="tt1">单个样式:css()内"属性名称","value"< ...
- Linux脚本程序
#!/bin/bash # array-ops.sh: 数组更多有趣的用法. array=( zero one two three four five ) # 元素 ]} # zero } # zer ...
- ssh 多次登录禁用账号
vi /etc/pam.d/sshd #%PAM-1.0auth required pam_tally2.so deny=3 unlock_time=600 even_deny_root root_u ...
- [Web 前端] VML、SVG、Canvas简介
1.VML: VML的全称是Vector Markup Language(矢量可标记语言),矢量的图形,意味着图形可以任意放大缩小而不损失图形的质量,这在制作地图上有很大用途,VML只是被IE支持. ...
- SharePoint每日小贴士Web部件
SharePoint每日小贴士Web部件 项目描写叙述 此Web部件从指定SP自己定义列表或一个选定的 RSS源选择一个随机项目.并显示一张图片.标题和一个Tip. 适 ...