当前位置:首页 » SEO知识

设计模式:学习笔记(2)——观察者模式

2017-03-16 11:40 本站整理 浏览(4)

Java设计模式之观察者模式

引入观察者模式

什么是观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新
   就好像下面这样:当主题对象中的一些状态发生改变时,就会通知他的观察者,狗、猫、鸭子等,但是牛并不是观察者,所以不会收到通知。
  

从这幅图我们发现:

☐ 所有的观察者都需要遵守一定的准则,才能区别于非观察者对象。观察者会收到通知并更新,说明他们有一个共同的方法,可以是update(),故我们可以让他们继承同一个接口。

☐ 主题对象一定是有一个观察者列表,并且这个列表可以动态更新,他在通知时可以根据列表来推送消息。

观察者模式的类图

说明:

Subject是主题接口,使用此接口中的RegisterObserver来注册接口,等等。 所有潜在的观察者必须实现观察者接口,这个接口只有Update()一个方法,当主题状态改变时它被调用。

观察者模式的Java内置支持

构建观察者与主题对象

所有的观察者实现Java内置接口Observer

我们一共实现了三个观察者


被观察者即主题对象需要继承Observable类

public class SubjectObserable  extends Observable {
    ....
}
说明:   一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。

观察者如何发出通知

你需要利用扩展Observable类产生可观察者类(主题对象),然后需要两个步骤:
1.调用setChanged()方法,标记状态已经改变的事实。
2.然后调用notifyObservers()方法中的一个。

public class SubjectObserable  extends Observable {
    private String food ="rice";
    public void foodChanged()
    {
        food="fish";
        setChanged(); //标记改变
        notifyObservers(food); //传送数据
    }

    public static void main(String[] args) {
        SubjectObserable subject = new SubjectObserable();
        DogObserver dog = new DogObserver(subject);
        CatObserver cat = new CatObserver(subject);
        MouseOberser mouse = new MouseOberser(subject);
        subject.foodChanged();
    }
}

观察者如何接收通知

同样观察者实现了update()方法:update(Observable o,Object arg)
☐ 主体本身被当做一个变量,好让观察者知道是那个主题通知了它.
☐ 传入给notify的数据对象,如果没有则说明为空.

public class CatObserver  implements Observer {
    Observable observable;
    public CatObserver(Observable observable)
    {
        this.observable =observable;
        observable.addObserver(this);//将其添加至观察者
    }

    public void update(Observable o, Object arg) {
        System.out.println("Cat:"+arg);
    }
}

观察者主动获取状态信息

为什么要主动获取信息

在前面,我们所讲的都是主题对象主动推送信息给观察者,但是观察者种类众多,有时我们无法事先料到所有的观察者的需求,还是让我们直接去获取我们需要的状态比较恰当,这样一来,如果我们某些观察者只需要一点点数据,就不会强迫获得一堆数据.这样做同时也比较容易修改.比方说,那天你决定扩展功能,你就不用修改和更新对每位观察者的调用.

如何实现主动获取

主题对象

public class SubjectObserable  extends Observable {
    private String food ="rice";
    public void foodChanged()
    {
        setFood("fish");
        setChanged(); //标记改变
        notifyObservers(); //不传送数据,只是通知状态改变
    }

    public String getFood() { //提供此方法,让观察者主动获取
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }
 }

观察者对象

public class CatObserver  implements Observer {
    Observable observable;
    public CatObserver(Observable observable)
    {
        this.observable =observable;
        observable.addObserver(this);
    }

    public void update(Observable o, Object arg) {
        if(o instanceof SubjectObserable)
        {
            SubjectObserable subjectObserable = (SubjectObserable) o;

            System.out.println("我知道已经改变.我主动获取信息:"+subjectObserable.getFood());
        }
        System.out.println("Cat:"+arg);
    }
}