观察者模式
参考:
http://blog.csdn.net/xiehuimx/article/details/60872690
http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
<大话设计模式>
在这里subject是抽象出来的通知者基类,Observer是观察者基类。在通知者中有一个观察者的列表,当观察者订阅的事件发生时,通知者就去遍历注册过来的观察者,然后逐一去告知观察者该执行什么动作。
这里是一个简单的例子。
总结:对于不同的动作我们可以添加不同的通知者,供观察者去订阅。
PictureDownLoadSubject:图片下载的实现者和通知者,负责下载图片和通知对应的订阅者。
PictureDownLoadObserver:图片下载的订阅者和发起人,它实现了下载观察者的基类方法,并通过图片下载通知者去下载想要的图片并希望得到每个阶段的通知。
java的java.util库中提供了一个Ovserverable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
public interface Observer { void update(Observable o, Object arg); }该类中有两个方法对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。
setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。
notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
public class Observable {
private boolean changed = false;
private Vector obs;
/** Construct an Observable with zeroObservers. */
public Observable() {
obs = new Vector();
}
/**
* 将一个观察者添加到观察者聚集上面
*/
public synchronized voidaddObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 将一个观察者从观察者聚集上删除
*/
public synchronized voiddeleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
/**
* 如果本对象有变化(那时hasChanged 方法会返回true)
* 调用本方法通知所有登记的观察者,即调用它们的update()方法
* 传入this和arg作为参数
*/
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--)
((Observer)arrLocal[i]).update(this, arg);
}
/**
* 将观察者聚集清空
*/
public synchronized void deleteObservers(){
obs.removeAllElements();
}
/**
* 将“已变化”设置为true
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* 将“已变化”重置为false
*/
protected synchronized void clearChanged(){
changed = false;
}
/**
* 检测本对象是否已变化
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this<tt>Observable</tt> object.
*
* @return the number of observers of this object.
*/
public synchronized int countObservers() {
return obs.size();
}
}
在这个模式中,我总觉得耦合程度有点高。
观察者observer需要持有observable(即被观察者/订阅者)对象,数据的变化需要在observable中进行,observer发起动作之后调用observable处理对象方法,并由其去接手并做相应的数据处理。
observable中必须持有observer对象,在做完相应的工作之后通知observer中对应的处理方法。