今天在做Oozie的项目的时候,想要对后台的作业任务进行实时监控,想了好久都没有办法,因为没有源码,只有接口,所以最终没有搞成,用了自我感觉比较恶心的定时请求的方法....额,说了这么多好像和主题没什么关系,那好吧,进入正题。我们很多时候都希望有一个类或者什么可以发现某个状态的变化,一旦状态发生变化,我们就可以得到通知,就像是有一个观察者一直在看着这个状态,一旦变化,他就告诉所有需要知道该变化的人。这就是——观察者设计模式。
好了,废话不多说,上类图(其实自己也发现,有了类图,理解问题就变得简单和直观很多了)。
这个类图,看了以后,其实还有很多细节,用语言来描述的话,其实关键点就在于:当产生数字的时候,给所有的观察者通知,这个通知的完成,是因为观察者都有一个产生数字的抽象类的引用。下面我们来看看代码的实现吧。
产生数字的抽象类:
package com.xdccl.zwj.ObserverDesignPattern;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class NumberGenerator {
private List<Observer> observers = new ArrayList<Observer>() ;
//添加观察者
public void addObserver(Observer observer){
observers.add(observer) ;
}
//删除观察者
public void delObserver(Observer observer){
observers.remove(observer);
}
//通知观察者
public void notifyObserver(){
Iterator<Observer> iterator = observers.iterator() ;
while(iterator.hasNext()){
Observer o = iterator.next() ;
o.update(this) ;
}
}
public abstract int getNum() ;
public abstract void generate() ;
}
继承上面抽象类的随机产生随机数字的类:
package com.xdccl.zwj.ObserverDesignPattern;
import java.util.Random;
public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();//随机数
private int number; //数字
@Override
public int getNum() {
return number;
}
@Override
public void generate() {
for(int i=0 ; i < 5; i++) {
number = random.nextInt(10);//产生10以内的随机数
notifyObserver(); //如果有新产生的数字,就发出通知给所有注册过的观察者
}
}
}
观察者接口:
package com.xdccl.zwj.ObserverDesignPattern;
public interface Observer {
public abstract void update(NumberGenerator generator) ;
}
数字观察者:
package com.xdccl.zwj.ObserverDesignPattern;
public class NumberObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("NumberObserver:"+ generator.getNum());
try {
Thread.sleep(1000 * 3); //为了能清楚的看到输出,休眠3秒钟。
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
客户端:
package com.xdccl.zwj.ObserverDesignPattern;
public class Client {
public static void main(String args[]){
//实例化数字产生对象
NumberGenerator generator = new RandomNumberGenerator();
//实例化观察者
Observer observer = new NumberObserver();
//注册观察者
generator.addObserver(observer);
generator.generate(); //产生数字
}
}
如果发现下列结果,应该就没有问题:
NumberObserver:3
NumberObserver:9
NumberObserver:1
NumberObserver:1
NumberObserver:1
这里产生五次是因为,我设置的是产生5个随机数,每产生一个随机数都通知所有的观察者。
如上所述,观察者设计模式就是这个样子的。