Java_观察者模式(Observable和Observer)
http://blog.csdn.net/tianjf0514/article/details/7475164/
一、观察者模式介绍
在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。
如果画面A是显示数据库里面的数据,而画面B修改了数据库里面的数据,那么这时候画面A就要重新Load。这时候就可以用到观察者模式
二、观察者模式实现方法
java.util.Observable中有两个方法对Observer特别重要
①setChanged()方法
- /**
- * Sets the changed flag for this {@code Observable}. After calling
- * {@code setChanged()}, {@code hasChanged()} will return {@code true}.
- */
- protected void setChanged() {
- changed = true;
- }
②notifyObservers()方法 / notifyObservers(Object data)方法
- /**
- * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
- * method for every observer in the list of observers using null as the
- * argument. Afterwards, calls {@code clearChanged()}.
- * <p>
- * Equivalent to calling {@code notifyObservers(null)}.
- */
- public void notifyObservers() {
- notifyObservers(null);
- }
- /**
- * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
- * method for every Observer in the list of observers using the specified
- * argument. Afterwards calls {@code clearChanged()}.
- *
- * @param data
- * the argument passed to {@code update()}.
- */
- @SuppressWarnings("unchecked")
- public void notifyObservers(Object data) {
- int size = 0;
- Observer[] arrays = null;
- synchronized (this) {
- if (hasChanged()) {
- clearChanged();
- size = observers.size();
- arrays = new Observer[size];
- observers.toArray(arrays);
- }
- }
- if (arrays != null) {
- for (Observer observer : arrays) {
- observer.update(this, data);
- }
- }
- }
以上两个方法十分重要
setChanged()方法 ——
用来设置一个内部标志位注明数据发生了变化
notifyObservers()方法 / notifyObservers(Object data)方法 ——
通知所有的Observer数据发生了变化,这时所有的Observer会自动调用复写好的update(Observable observable, Object data)方法来做一些处理(比如说画面数据的更新)。
我们可以看到通知Observer有两个方法,一个无参,一个有参。那么这个参数有什么作用呢?
其中一个作用:现在我不想通知所有的Observer,而只想其中一个指定的Observer做一些处理,那么就可以传一个参数作为ID,然后在所有的Observer中判断,每个Observer判断只有接收到底参数ID是属于自己的才做一些处理。
当然参数还有其他作用,我只是举了个例子。
下面举个例子加以说明:
- import java.util.Observable;
- /**
- * 被观察者类
- */
- public class SimpleObservable extends Observable
- {
- private int data = 0;
- public int getData(){
- return data;
- }
- public void setData(int i){
- if(this.data != i) {
- this.data = i;
- setChanged();
- //只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
- notifyObservers();
- }
- }
- }
上面这个类是一个被观察者类,它继承了Observable类,表示这个类是可以被观察的。
然后在setData()方法里面,也就是数据改变的地方,来调用Observable类的setChanged()方法和notifyObservers()方法,表示数据已改变并通知所有的Observer调用它们的update()方法做一些处理。
注意:只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
- /**
- * 观察者类
- */
- public class SimpleObserver implements Observer
- {
- public SimpleObserver(SimpleObservable simpleObservable){
- simpleObservable.addObserver(this );
- }
- public void update(Observable observable ,Object data){ // data为任意对象,用于传递参数
- System.out.println(“Data has changed to” + (SimpleObservable)observable.getData());
- }
- }
通过生成被观察者(SimpleObservable类)的实例,来调用addObserver(this)方法让观察者(SimpleObserver类)达到观察被观察者(SimpleObservable类)的目的。
然后还要复写update()方法,做数据改变后的一些处理。
下面可以写一个简单的测试类来测试一下
- public class SimpleTest
- {
- public static void main(String[] args){
- SimpleObservable doc = new SimpleObservable ();
- SimpleObserver view = new SimpleObserver (doc);
- doc.setData(1);
- doc.setData(2);
- doc.setData(2);
- doc.setData(3);
- }
- }
运行结果如下
- Data has changed to 1
- Data has changed to 2 //第二次setData(2)时由于没有setChange,所以update没被调用
- Data has changed to 3
下面介绍一个Observable类的其他一些属性和方法
属性 ——
- // observers是一个List,保存着所有要通知的observer。
- List<Observer> observers = new ArrayList<Observer>();
- // changed是一个boolean型标志位,标志着数据是否改变了。
- boolean changed = false;
方法 ——
- // 添加一个Observer到列表observers中
- public void addObserver(Observer observer) {
- if (observer == null) {
- throw new NullPointerException();
- }
- synchronized (this) {
- if (!observers.contains(observer))
- observers.add(observer);
- }
- }
- // 从列表observers中删除一个observer
- public synchronized void deleteObserver(Observer observer) {
- observers.remove(observer);
- }
- // 清空列表observers
- public synchronized void deleteObservers() {
- observers.clear();
- }
- // 返回列表observers中observer的个数
- public int countObservers() {
- return observers.size();
- }
- // 重置数据改变标志位为未改变
- protected void clearChanged() {
- changed = false;
- }
- // 将数据改变标志位设置为改变
- protected void setChanged() {
- changed = true;
- }
- // 判断标志位的值
- public boolean hasChanged() {
- return changed;
- }
- // 通知所有observer(无参)
- public void notifyObservers() {
- notifyObservers(null);
- }
- // 通知所有observer(有参)
- @SuppressWarnings("unchecked")
- public void notifyObservers(Object data) {
- int size = 0;
- Observer[] arrays = null;
- synchronized (this) {
- if (hasChanged()) {
- clearChanged();
- size = observers.size();
- arrays = new Observer[size];
- observers.toArray(arrays);
- }
- }
- if (arrays != null) {
- for (Observer observer : arrays) {
- observer.update(this, data);
- }
- }
- }
注意:在Observer对象销毁前一定要用deleteObserver将其从列表中删除,也就是在onDestroy()方法中调用deleteObserver()方法。
不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。
下面2个工程是Observable与Observer的经典运用,是Android实现的单指拖动放大图片的操作
两个例子:
Java_观察者模式(Observable和Observer)的更多相关文章
- java中观察者模式Observable和Observer
25.java中观察者模式Observable和Observer 如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口 观察者设计模式 现在很多的 ...
- 设计模式之观察者模式(Observable与Observer)
设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...
- 25、java中观察者模式Observable和Observer
如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口 观察者设计模式 现在很多的购房者都在关注着房子的价格变化,每当房子价格变化的时候,所有的购房 ...
- Java_观察者模式(Observable和Observer) -转
原文地址: Java_观察者模式(Observable和Observer) 一.观察者模式介绍 在Java中通过Observable类和Observer接口实现了观察者模式.一个Observer ...
- 十一、观察者模式(Observable、Observer)
老板出差了,员工1.员工2..均放羊中.他们请求前台的秘书,当老板回来时通知自己,免得被Boss抓个现行.秘书想了想,说————嗯,这是观察者模式. 当一个对象的改变需要同时改变其它对象,而且它不知道 ...
- RxJava 设计理念 观察者模式 Observable lambdas MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- [RxJS] Subject: an Observable and Observer hybrid
This lesson teaches you how a Subject is simply a hybrid of Observable and Observer which can act as ...
- OpenJDK源码研究笔记(六)--观察者模式工具类(Observer和Observable)和应用示例
本文主要讲解OpenJDK观察者模式的2个工具类,java.util.Observer观察者接口,java.util.Observable被观察者基类. 然后,给出了一个常见的观察者应用示例. Obs ...
- Java常用类库--观察者设计模式( Observable类Observer接口)
如果要想实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口. import java.util.* ; class House extends Obse ...
随机推荐
- 一、IOS运行原理
1.首先执行main函数 2.执行UIPaalicationMain函数 3.UIApplication函数内部 1>创建一个UIApplication实例.这个UIApplication对象是 ...
- title与h1的区别
title与h1的联系: 从网站角度看,title更重于网站信息.title可以直接告诉搜索引擎和用户这个网站是关于什么主题和内容的. 从文章角度看,h1则是用于概括文章主题.用户进入内容页,想看到的 ...
- android volley get请求使用
调用百度api微博热门精选接口,使用了volley,简单说说volley get的请求方式的使用 header的设置和请求参数的设置,见代码如下: private void getWeixinNews ...
- 使用dynamic获取类型可变的json对象
标题可能有点含糊不清 我这个例子的来源是,对方会返回给我json,不过成功的json与失败的json是不同的对象 我想用一个方法获取到这个对象的所有属性并打印到log中 因为是动态变化的,所以第一个想 ...
- Android 下的EXIF
一.什么是Exif Exif(Exchangeable Image File 可交换图像文件)是一种图象文件格式,它的数据存储与JPEG格式是完全相同的.实际上Exif格式就是在JPEG格式头部插入了 ...
- C语言 百炼成钢17
//题目49:老师将糖果分成若干份,让学生按任意次序领取,第一个领取的,得到1份加上剩余糖果的1/10, //第二个领取的,得到2份加上剩余糖果的1/10,第三个领取的,得到3份加上剩余糖果的1/10 ...
- Returns: range-based (not absolute) index within the current range
/** * This method is for use with UI Table addRows buttons that require the * addition of multiple r ...
- [CareerCup] 7.6 The Line Passes the Most Number of Points 经过最多点的直线
7.6 Given a two-dimensional graph with points on it, find a line which passes the most number of poi ...
- 初识 swift 封装轮播图
一.简介 换了一家公司.换了一个环境刚开始来公司自然不能有一丝一毫的放松,每天即使是没有什么工作也是看看这个博客.那个源码.尽量让自己更充实.慢慢的开始写几篇博客记录下自己遇到的一些问题和解决方法.其 ...
- Java并发编程-CopyOnWriteArrayList
CopyOnWriteArrayList原理 首先每次写操作,都将数组copy一份,并赋值给arrays 读操作读不加锁 写操作加锁 ReentrantLock 因为每次写都要copy数组,这是一项繁 ...