设计模式之观察者模式

来源:互联网 发布:淘宝申请客服介入流程 编辑:程序博客网 时间:2024/06/06 00:13
一、定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变时,它的所有依赖者都会收到通知,并自动更新。



二、示例:观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口,并用此观察者接口更新观察者。

     1、 自定义实现观察者模式。

//可观察者接口,观察者实现此接口,方便观察者的注册与移除public interface Observable{ //观察者注册方法public void addObserver(Observer observer);//观察者的移除方法public void delObserver(Observer observer);//可观察者发生变化时调用该方法通知所有观察者public void notifyObservers();} //观察者接口,所有的观察者都必须实现update()方法,以实现观察者接口。public interface Observer{//当可观察者状态发生改变时,会通过此方法将状态值(obj)传给观察者,o用来标识是哪个可观察者public void update(Observable o,Object obj);} //某一可观察者,实现可观察者接口public class Subject implements Observable{//存储注册此可观察者的观察者集合private ArrayList<Observer> observers;//可观察者的状态对象,可改成任意需要的对象private Object mObject; public Subject(){ //初始化集合,用于保存所有注册此可观察者的观察者 observers=new ArrayList<Observer>();} //注册观察者public void addObserver(Observer observer){ observers.add(observer);//只需将观察者添加进观察者集合} //移除观察者public void delObserver(Observer observer){ int i=observers.indexOf(o); if(i>=0){ observers.remove(i);//将观察者从观察者集合中移除 }} //通知观察者们,数据已经变化public void notifyObservers(){for(int i=0;i<observers.size();i++){ Observer observer = observers.get(i); observer.update(this,mObject); }}  //数据改变时调用的方法,在状态值发生改变并想通知观察者的地方调用public void dataChanged(){notifyObservers();} //可观察者的其他代码逻辑...... } //某一观察者,实现观察者接口public class DataDisplay implements Observer{//对可观察者的引用,以便在不需要继续观察的时候将自己从可观察者中移除private Observerable mSubject; public DataDisplay(Observable subject){ this.mSubject=subject; subject.addObserver(this);//将直接注册成为观察者} public void update(Observable o,Object obj){ //当可观察者状态发生改变时此方法会被调用,将状态发生变化的可观察者以及状态参数传递过来 //实现自己的代码逻辑 ...... } }


    2、 java内置的观察者模式:java.util包中包含了最基本的Observer接口和Observable类,和上面我们自定义的两个接口类似,使用上更方便,而且可以使用推或拉两种方式从可观察者中获取状态值。

     ① 把对象变成观察者:通过实现观察者接口(java.util.Observer),然后调用任何Observable对象的addObserver()方法将自己注册为观察者;当不想成为观察者时调用deleteObserver()方法就可以了。
      
      ② 可观察者发送通知:通过继承java.util.Observable类将自己变为可观察对象,然后先调用setChanged()方法,标记状态已经改变的事实;然后调用notifyObservers()或notifyObservers(Object obj)发送通知。
      
      ③ 观察者接收通知:观察者实现了Observer接口后会默认实现update(Observable o,Object obj),当可观察者发送通知时update方法会回调。此方法中将可观察者自身作为第一个变量,好让观察者知道是哪个可观察者通知它的;第二个参数obj就是notifyObservers(Object obj)中的参数obj。


     我们注意到,在可观察对象发送通知前必须调用 setChanged()方法设置状态已经改变的事实,然后再调用两种notifyObservers()方法之一才会真正的通知观察者,这样一来,就可以使我们更灵活的应用通知,其实现原理也很简单:

setChanged(){changed=true;//把changed标志设为true}     notifyObservers(Object obj){if(changed){//只会在changed标为"true"时通知观察者for every observer on the list{call update(this,obj);}}changed=false;//在通知观察者之后,把changed标志设回false}


三、总结:java内置的java.util.Observable类虽然使用起来非常简便,但是它也有一些黑暗面,首先,Observable是一个类,而不是接口,甚至没有实现一个接口,这样的话,如果某个类想同时具有Observable类和另一个超类的行为,就会陷入两难;另外,Observable类将关键的方法(如setChanged()方法)保护起来了,除非继承自Observable,否则无法创建Observable实例并组合到自己的对象中来;最后有一点需要注意的是,当有多个观察者时,不可以依赖特定的通知次序,就是说可观察者通知观察者的次序是不固定的,如果依赖通知次序实现某些功能,结果会不尽人意。所以,如果内置的观察者模式能够满足我们的需求是,可以使用内置的观察者模式,毕竟它们已经帮我们实现了很多逻辑,使用起来更方便,但是如果java内置的观察者模式使用时得到了限制,不妨实现自己的观察者模式,毕竟原理我们已经很清楚。

0 0