设计模式之(二)——观察者模式(Observer Pattern)

观察者模式定义对象之间一对多依赖,一个对象改变状态的时候,所有依赖者会收到通知并自动更新。


拿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();
    }
}


由代码可以看出,观察者依赖于主题对象,但是每个观察者都是独立的,代码可以针对特定的观察者进行修改。
主题能通知到所有观察者,只要观察者是注册过该主题,但是主题并不知道都有哪些,只负责把注册过自己的观察者一一通知。
不过缺点是,如果观察者数量庞大的话,将主题变化全部通知到的时间花费是非常长的。

场景应用:
这种一个通知多个对象进行响应的模式可以利用在,比如某个号码中奖了,通知对应的中奖人中奖。
 

猜你喜欢

转载自blog.csdn.net/iaiti/article/details/77203443