观察者模式定义对象之间一对多依赖,一个对象改变状态的时候,所有依赖者会收到通知并自动更新。
拿JDK中已经实现的主题对象的父类Observable和观察者需要实现的接口Observer
Observable可观察的,即可被观察者观察到的主题对象。
查看源码
public abstract interface Observer
{
public abstract void update(Observable paramObservable, Object paramObject);
}
观察者需要实现update接口,至于原因再看下Observable类。
//使用Vector保存注册进来的观察者对象。Vector相对于Arraylist是线程安全的。
private Vector<Observer> obs;
//相当于遍历整个vector,再调用注册的Observer update接口,这就是为什么接口的通用方法是update。
public void notifyObservers(Object paramObject)
假设我们的主题是动物生活的地方,观察者是动物们。写个简单的示例。
动物园能通知动物吃和睡。
package Observer;
import java.util.Observable;
public class Zoo extends Observable{
private String eatNotify ;
private String sleepNotify ;
public void notifyToSend(){
setChanged();
notifyObservers();
}
public void notifyAll(String eatNotify,String sleepNotify){
this.eatNotify = eatNotify;
this.sleepNotify = sleepNotify;
notifyToSend();
}
public String getEatNotify() {
return eatNotify;
}
public void setEatNotify(String eatNotify) {
this.eatNotify = eatNotify;
}
public String getSleepNotify() {
return sleepNotify;
}
public void setSleepNotify(String sleepNotify) {
this.sleepNotify = sleepNotify;
}
}
而老虎对于吃睡的要求有具体反馈,但是根据主题对象的变化通知来。
package Observer;
import java.util.Observable;
import java.util.Observer;
public class Tiger implements Observer, AnimalAction {
Observable animalPlace;
private String eatNotify;
private String sleepNotify;
@Override
public void update(Observable paramObservable, Object paramObject) {
if (paramObservable instanceof Zoo) {
Zoo zoo = (Zoo) paramObservable;
this.eatNotify = zoo.getEatNotify();
this.sleepNotify = zoo.getSleepNotify();
action();
}
}
public Tiger(Observable animalPlace) {
this.animalPlace = animalPlace;
animalPlace.addObserver(this);
}
@Override
public void action() {
System.out.println("Meat : " + eatNotify + " , Cool ground :" + sleepNotify);
}
}
动物园发送通知
package Observer;
public class ZooNotify {
public static void main(String[] args) {
Zoo zoo = new Zoo();
zoo.setEatNotify("Eat 7AM");
zoo.setSleepNotify("Sleep 9PM");
new Tiger(zoo);
zoo.notifyToSend();
}
}
由代码可以看出,观察者依赖于主题对象,但是每个观察者都是独立的,代码可以针对特定的观察者进行修改。
主题能通知到所有观察者,只要观察者是注册过该主题,但是主题并不知道都有哪些,只负责把注册过自己的观察者一一通知。
不过缺点是,如果观察者数量庞大的话,将主题变化全部通知到的时间花费是非常长的。
场景应用:
这种一个通知多个对象进行响应的模式可以利用在,比如某个号码中奖了,通知对应的中奖人中奖。