转载请注明出处:http://blog.csdn.net/crazy1235/article/details/51815880
观察者模式 又称为 发布-订阅模式 。定义了一种一对多的依赖关系,当被观察者对象状态发生改变时,通知所有依赖于它(订阅它)的观察者对象。
RSS订阅 和 邮件订阅 大家应该都知道,你订阅后,将会及时获得所订阅的相关最新内容。所有订阅该内容的“订阅者”,当该内容有更新时,就可以收到通知。这就是一种观察者模式的应用场景。
java中,内置了Observer和Observable,分别表示抽象的观察者对象和抽象主题角色(可被观察,被观察者)。
Observer是一个借口,定义了一个update方法。
public interface Observer {
void update(Observable o, Object arg);
}
先来看看JDK中Observer和Observable的源码。
public interface Observer {
/** * 更新操作 */
void update(Observable o, Object arg);
}
该类是一个 接口 ,只有一个更新的函数。
package java.util;
/** * 表示一个可被观察的对象 * 一个被观察者可以有多个观察者对象 * 调用 notifyObservers 方法可以通知所有的观察者调用他们的 update 方法 * 当一个被观察者被初始创建的时候,它的观察者set集合是空的 */
public class Observable {
private boolean changed = false;
private Vector<Observer> obs; // 通过向量保存观察者对象
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector<>();
}
/** * 添加一个观察者对象 * * @param o an observer to be added. * @throws NullPointerException if the parameter o is null. */
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/** * 删除一个观察者对象 * * @param o the observer to be deleted. */
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
/** * 当对象发生变化是,首先调用hasChanged表明发生了改变,然后通知所有的观察者对象,调用它们各自的update方法,最后调用clearChanged方法表明当前对象已经没有改变了。 * 每个观察者对象都有它的update方法,该方法有两个参数 * * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */
public void notifyObservers() {
notifyObservers(null);
}
/** * arg参数最终会赋值给update函数的第二个参数 * * @param arg any object. * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
//由此可以看书,如果没有changed == false,直接return,后序代码不执行。
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
//倒序遍历观察者对象数组,调用update方法。由此看出,后添加进来的观察者对象会被先调用update方法。
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
/** * 清楚所有的观察者对象 */
public synchronized void deleteObservers() {
obs.removeAllElements();
}
/** * 设置改变标志,只有调用了该方法,观察者对象才能被通知。 */
protected synchronized void setChanged() {
changed = true;
}
/** * 重置改变标志 * * @see java.util.Observable#notifyObservers() * @see java.util.Observable#notifyObservers(java.lang.Object) */
protected synchronized void clearChanged() {
changed = false;
}
/** * 判断是否有改变 * * @see java.util.Observable#clearChanged() * @see java.util.Observable#setChanged() */
public synchronized boolean hasChanged() {
return changed;
}
/** * 返回观察者对象的数量 */
public synchronized int countObservers() {
return obs.size();
}
}
/** * 被观察者类 继承Observable类,表示这个类可以被观察。 * * @author Admin * */
public class SimpleObservable extends Observable {
private int data = 0;
public int getData() {
return data;
}
public void setData(int data) {
if (this.data != data) {
this.data = data;
// 标志状态改变,一定要调用函数notify方法才有效
setChanged();
// 通知所有观察者
notifyObservers("abc");
}
}
}
/** * 观察者1号 * * @author Admin * */
public class SimpleObserver implements Observer {
public SimpleObserver(SimpleObservable simpleObservable) {
simpleObservable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("SimpleObserver: " + ((SimpleObservable) o).getData() + " -- " + (String)arg);
}
}
/** * 观察者2号 * @author Admin * */
public class OtherObserver implements Observer{
public OtherObserver(SimpleObservable observable){
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("OtherObserver: " + ((SimpleObservable)o).getData() + " -- " + (String)arg);
}
}
public class SimpleTest {
public static void main(String[] args) {
SimpleObservable observable = new SimpleObservable();
new OtherObserver(observable);
new SimpleObserver(observable);
observable.setData(1);
observable.setData(2);
observable.setData(2);
observable.setData(4);
}
}
测试的结果如下:
SimpleObserver: 1 -- abc
OtherObserver: 1 -- abc
SimpleObserver: 2 -- abc
OtherObserver: 2 -- abc
SimpleObserver: 4 -- abc
OtherObserver: 4 -- abc
上面介绍的都是同步观察者模式。同步观察者模式会有阻塞问题。各个观察者按照顺序执行update方法。一旦有一个observer比较耗时的话,后序的observer也得等着。
异步观察者模式就不一样,不会有这样的阻塞问题。
针对update方法做文章 。
/** * 异步观察模式的观察者接口 */
public interface AsyncObserver {
/** * * @param o * @param arg */
void update(AsyncObservable o, Object arg);
}
/** * 异步观察者模式的被观察者对象 */
public class AsyncObservable {
private boolean changed = false;
private Vector<Wrapper> obs;
public AsyncObservable() {
obs = new Vector<>();
}
/** * * @param wrapper */
public synchronized void addObserver(AsyncObserver o) {
if (o == null)
throw new NullPointerException();
Wrapper wrapper = new Wrapper(o);
if (!obs.contains(wrapper)) {
obs.addElement(wrapper);
}
}
/** * */
public synchronized void deleteObserver(AsyncObserver o) {
Iterator<Wrapper> iterator = obs.iterator();
while (iterator.hasNext()) {
Wrapper wrapper = iterator.next();
if (wrapper.getAsyncObserver() == o) {
obs.remove(wrapper);
break;
}
}
}
/** * */
public void notifyObservers() {
notifyObservers(null);
}
/** * */
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length - 1; i >= 0; i--)
((Wrapper) 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();
}
}
/** * 观察者的包装类 */
public class Wrapper {
private AsyncObserver observer;
public Wrapper(AsyncObserver o) {
this.observer = o;
}
public AsyncObserver getAsyncObserver() {
return observer;
}
/** * * @param observable * @param o */
public void update(AsyncObservable observable, Object o) {
new Handler(observable, o).start();
}
class Handler extends Thread {
AsyncObservable observable;
Object object;
public Handler(AsyncObservable observable, Object o) {
this.observable = observable;
this.object = o;
}
@Override
public void run() {
observer.update(observable, object);
}
}
}
最主要的就是这个Wrapper包装类。被观察者的notify方法内部实际上调用的是Wrapper类中的update()方法。
将每个update操作放到一个线程中去。这样多个线程“同时”工作。
这样即是某些观察者类的update做一些耗时操作,也不影响其他观察者类的update的工作、
测试结果:
hahahaha
hahahaha
hahahaha
hahahaha
hahahaha
hahahaha
hahahaha
hahahaha
hahahaha
ObserverB -- i think jingjing -- jingjing
hahahaha
ObserverC -- i think jingjing -- jingjing
ObserverA -- i think jingjing -- jingjing
观察者模式中,被观察者与观察者通过接口进行联系。被观察者只知道一个观察者列表,列表中的每个对象都是一个抽象观察者接口。
Android中观察者模式的应用场景有:
广播机制
ListView数据更改
点击事件
ContentObserver
完毕。
:-D
晚安~