介绍这个模式使用的例子是一个气象检测应用的例子。采集数据,并显示在布告板上面。
系统的要求:数据采集完毕后会调用方法measurementchanged()方法,数据有变化的时候布告板要更新,系统可扩展,用户可以随心所欲添加删除布告板。
出版者+订阅者=观察者模式
系统的实现:
主题接口:interface Subject{注册观察者,删除观察者,提醒观察者}
主题实现类:ConcreteSubject{}
观察者接口:interface observer{update()}
观察者实现:ConcreteObserver(){}
观察者模式的目的是使得主题和观察者之间松耦合。
关于耦合的概念参考:
http://baike.baidu.com/view/1343493.htm
设计原则:为了交互对象之间的松耦合设计而努力。
松耦合设计可以让我们建立有弹性的oo系统,能够应对变化,它把对象之间的相互依赖降到了最低。
再添加一个接口inteface DisplayElement{display()}
具体的显示面板需要实现两个接口Observer和DisplayElement。
在主题实现中,需要注意的有:
温度变化————>measurmentchanged()——————>notifyObsever这一系列的动作是一连串执行下来的。
现在系统有的问题是:已有温度变化就会使得显示板发生变化,这样很烦人,而且显示板只能被动的接受数据。
这样引出了“推push 拉pull”的概念,推就是主题把数据发给观察者,拉就是观察者自己取数据。
第一个问题可以给主题一个标记位,当温度改变达到一定范围后改变标记位,这样根据标记位来判断是否需要提醒观察者。书中用到的是java内置的观察者模式接口和类,推拉数据的话会由用户自己定义,下面是JavaObserable的notify方法实现:
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
它会把本对象提交给观察者,而观察者,需要实现Observer的update方法,该方法定义如下:
void update(Observable o, Object arg);
在该方法中可以抽取观察者希望的数据,起到了“拉”的效果。
今天的笔记就到这里,比较仓促,效果不太好,继续理解观察者模式ing....