分享

jdk自带Observer模式

 李副营长 2014-01-09

 观察者模式可以说是Java jdk中使用率最高的一个模式了.而且jdk也自带实现了观察者模式,可见这个模式的重要性.

java.util下的public interface Observer

一个可在观察者要得到 observable 对象更改通知时可实现Observer接口的类。

方法摘要
 void update(Observable o, Object arg)
          只要改变了 observable 对象就调用此方法。


java.util.Observable 类

public class Observable extends Object此类表示模型视图范例中的 observable 对象,或者说“数据”。可将其子类化,表示应用程序想要观察的对象。 
一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。 
未指定发送通知的顺序。Observable 类中所提供的默认实现将按照其注册的重要性顺序来通知 Observers,但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知,或者也可能保证其子类遵从其所选择的顺序。 
注意,此通知机制与线程无关,并且与 Object 类的 wait 和 notify 机制完全独立。 
新创建一个 observable 对象时,其观察者集是空的。当且仅当 equals 方法为两个观察者返回 true 时,才认为它们是相同的。
构造方法摘要
Observable()
          构造一个带有零个观察者的 Observable。
  
方法摘要
 void addObserver(Observer o)
          如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。
protected  void clearChanged()
          指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以hasChanged方法将返回false。
 int countObservers()
          返回Observable对象的观察者数目。
 void deleteObserver(Observer o)
          从对象的观察者集合中删除某个观察者。
 void deleteObservers()
          清除观察者列表,使此对象不再有任何观察者。
 boolean hasChanged()
          测试对象是否改变。
 void notifyObservers()
          如果hasChanged方法指示对象已改变,则通知其所有观察者,并调用clearChanged方法来指示此对象不再改变。
 void notifyObservers(Object arg)
          如果hasChanged方法指示对象已改变,则通知其所有观察者,并调用clearChanged方法来指示此对象不再改变。
protected  void setChanged()
          标记此Observable对象为已改变的对象;现在hasChanged方法将返回true。


样例:

是这样的,有一个酒店价格更新的业务逻辑.每当酒店总部调整价格的时候,各个下属酒店的价格将发生变化.
我们在这里,将房间分为了normal,advanced,top三种.每种的价格都是由酒店总部调整.
首先运用观察者模式,写出核心类,在这里我得理解为核心类,这个核心类将会把最新的一些数据自动发生给各个下属酒店.

下面这个是观察者模式的核心-----被观察者.

01package org.pattern.observer.jdk;
02 
03import java.util.Observable;
04 
05public class ObserverCore extends Observable {
06 
07    // 注意,我们继承了Observable,有很多方法供我们使用.
08    private double normal;
09    private double middle;
10    private double top;
11 
12    //这个方法用于更新最新的酒店价格.
13    public void inputPrice(double normal,double middle,double top) {
14        this.normal=normal;
15        this.middle=middle;
16        this.top=top;
17        this.sureToSendPrice();
18    }
19 
20    //两个方法意义见上面API,
21    public void sureToSendPrice() {
22        this.setChanged();//改变状态,change后卫true,开启发送必须先setChange.
23        notifyObservers();//通知观察者
24    }
25 
26    public double getNormal() {
27        return normal;
28    }
29 
30    public double getMiddle() {
31        return middle;
32    }
33 
34    public double getTop() {
35        return top;
36    }
37}
下面将是两个观察者.观察者必须实现Ovserver接口,并实现其update方法.判断后进行获取值的操作.
01package org.pattern.observer.jdk;
02 
03import java.util.Observable;
04import java.util.Observer;
05 
06public class HotelA implements Observer {
07 
08    Observable ober;
09 
10    public HotelA(Observable ob) {
11        this.ober = ob;
12        ob.addObserver(this);
13    }
14     
15    @Override
16    public void update(Observable o, Object arg) {
17        if(o instanceof ObserverCore){
18            ObserverCore observerCore=(ObserverCore) o;
19            this.show(observerCore.getNormal(),observerCore.getMiddle(),observerCore.getTop());
20        }
21    }
22     
23    public void show(double normal,double middle,double top){
24        System.out.println("Anormal:"+normal);
25        System.out.println("Amiddle:"+middle);
26        System.out.println("Atop:"+top);
27    }
28 
29}
01package org.pattern.observer.jdk;
02 
03import java.util.Observable;
04import java.util.Observer;
05 
06public class HotelB implements Observer{
07    Observable ober;
08     
09    public HotelB(Observable ob){
10        this.ober=ob;
11        ob.addObserver(this);
12    }
13 
14    @Override
15    public void update(Observable o, Object arg) {
16        if(o instanceof ObserverCore){
17            ObserverCore observerCore=(ObserverCore) o;
18            this.show(observerCore.getNormal(),observerCore.getMiddle(),observerCore.getTop());
19        }
20    }
21     
22    public void show(double normal,double middle,double top){
23        System.out.println("Bnormal:"+normal);
24        System.out.println("Bmiddle:"+middle);
25        System.out.println("Btop:"+top);
26    }
27 
28}
01package org.pattern.observer.jdk;
02 
03public class main1 {
04 
05    public static void main(String[] args) {
06        ObserverCore core=new ObserverCore();
07        //注意这里以及两个被观察者的构造方法
08        HotelA a=new HotelA(core);
09        HotelB b=new HotelB(core);
10         
11        core.inputPrice(1, 2, 3);
12        core.inputPrice(11, 22, 33);
13        core.inputPrice(111, 222, 333);
14    }
15 
16}

觉得没啥意思,直接代码也就看懂了.

关于通知的顺序

值得注意的Observable 类中所提供的默认实现将按照其注册的顺序来通知 Observers.但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知.

总之,绝对不要在观察者模式中试图去依赖次序.

其实我在这里想了会,感觉使用通知者模式,应用场景应该是多个被观察者(方便理解,可以认为这里的被观察者模式是webservice的接收数据的接口)之间并无关联的.执行的通知顺序并不重要,或者说可以不在意.

不好的地方

写到这里可以注意到,java自带的观察者模式是一个类而不是一个接口.那么这样就意味着要继承.而我们的设计原则是,多用组合,少用继承.

那么最好的方式就是去自己写一套观察着模式.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多