设计模式之观察者模式

来源:互联网 发布:网络工程项目 编辑:程序博客网 时间:2024/06/04 19:49

学习设计模式之——观察者模式

  • 观察者模式定义
    观察者定义了对象之间的一对多依赖,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。
    多的一方可以称为主题(Subject)接口,多的一方称为观察者(Observer)接口,对象使用主题接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者,所有潜在的观察者必须实现观察者接口,实现观察者接口特定的方法,当主题的状态发生以供改变时调用,一个具体的主题总是实现主题接口,除了注册和撤销方法之外,主题还应实现notifyObservers()方法,此方法用于在主题状态发生改变的时候更新所有的观察者,具体的主题也可能有设置和获取状态的方法,具体的观察者是实现观察者接口的任意类,观察者必须注册具体的主题,一遍接收更新。

  • 模式接口实例
    interface:
    Subject{
    registerObserver();
    removeObserver();
    notifyObservers();
    }
    Observer{
    update();
    }
    instance:
    ConcreteSubject implements Subject{
    List list;
    registerObserver(Observer o){
    list.add(o);
    }
    removeObserver(Observer o){
    list.remove(o);
    }
    notifyObservers(){
    for(Observer o : list){
    o.update();
    }
    }
    }
    ConcreteObserver implements Observer{
    Subject sub;
    update(){
    ………
    }
    }

  • 松耦合的威力
    当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
    关于观察者的一切主题只知道观察者实现了某个接口(Observer)。主题不需要知道观察者具体类是谁,做了些什么或其他任何细节。任何时候我们都可以添加新的观察者,因为主题唯一依赖的东西是一个实现了Observer接口的对象列表,所以我们可以随时增加观察者,事实上,在运行时我们可以用新的观察者取代现有的观察者,主题不会受到任何影响,同样的,也可以在任何时候删除某些观察者。
    有新类型的观察者出现的时候,主题的代码不需要高边。例如我们有个新的具体类需要当观察者。我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新类里实现此观察者接口,然后注册成为观察者即可,主题不在乎别的,他只会发送通知给所有实现了观察者接口的对象。
    我们可以以独立的复用主题或观察者,如果我们在其他的地方需要使用主题或观察者,可以轻易的复用,因为两者并非紧耦合,改变主题或者观察者一方,并不会影响另一方,因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由的改变他们。
    松耦合的设计之所以让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低。

  • java内置的观察者模式
    在Java api有内置的观察者模式,java.util包里包含最基本的Observer接口和Observable类,和上文中的两个接口类似,内置的实现很多功能都已经准备好了,甚至可以使用推(push)或拉(pull)的方式传送数据。
    使用的方式如同以前一样,观察者实现观察者接口java.util.Observer,然后调用任何Observable对象的addObserver()方法,不想当观察者调用deleteObserver()方法。
    当可观察者发送通知时,需要两个步骤:1,先调用setChange()方法,标记状态已经发生改变的事实。2,然后调用两种notifyObservers()方法中的一个:notifyObservers()或notifyObservers(Object arg)。
    观察者通过update(Observable o, Object arg)方法获取通知,第一个变量为主题本身,第二个参数为notifyObservers方法传入的数据对象,如果你想推数据给观察者,你必须把数据对象传递给notifyObservers(org)方法,否则观察者必须从主题对象中拉数据

  • 编程原则
    封装变化,与程序中不变的方面分离
    多用组合,少用继承
    针对接口编程,不针对实现编程
    为交互对象之间的松耦合设计而努力


内容来自 head first design patterns 一书

原创粉丝点击