java 中已经有观察者模式的相关Api
在java.util包中
观察者 java.util.Observer
被观察者 java.util.Observable
java.util.Observable.notifyObservers()方法相关源码
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);
}
被观察者
public class ConcreteSubject extends Observable {
//具体的业务
public void doSomething(){
/*
* 具体的业务实现
*/
//调用 Observable 的notifyObservers方法
super.notifyObservers();
}
}
观察者
public class ConcreteObserver implements Observer {
//实现更新方法
public void update(Observable observable,object obj){
System.out.println("接收到信息,并进行处理");
}
}
java.util.Observer 要求update 必须传Observable和object参数
这样java已经帮我们实现了底层框架,也就是站在巨人的肩膀上
项目中真实的观察者模式
1.观察者和被观察者之间的消息沟通
被观察者状态改变会触发观察者的一个行为,同时会传递一个消息给观察者,一般项目中会接收两个参数,一个是被观察者,一个DTO(数据传输对象)
2.观察者的响应方式
在一个观察者有多个被观察者时,性能就得开始考虑了,
一般是使用多线程技术,或者是缓存技术
3.被观察者尽量自己做主
因为不是所有被观察者的动作都需要通知观察者,一般我们会重载被观察者的doSomething方法,例如 doSomething(boolean isNotifyObs) 来决定是否通知观察者,而不是在消息已经到达观察者时才进行判断
最佳实践
1.文件系统,
比如新建一个文件,这个动作会同时通知目录管理器增加目录,并通知磁盘管理器减少1kb 在这里"文件"是一个被观察者,"目录管理器"和"磁盘管理器"则是观察者
2.广播收音机
电台是被观察者,多个收音机则是观察者