首页 > 代码库 > Design Model---Observer Model

Design Model---Observer Model

  昨天看了Head First设计模式这本书,这本书写得真不错,简单易懂。我是第一次接触设计模式,觉得这东西挺高端大气的,和别人侃的时候,我用啥XX设计模式,是不是觉得很屌的感觉?哈哈,开玩笑了,主要是学习前人的经验,这样让自己的代码设计更加规范。现在就记录一下我学到的第一个设计模式---Observer Model

     什么是观察者设计模式呢?

     举个例子来说,就是报社和报纸订阅者的关系,报社一旦有新的报纸,就会推送给订阅了它的阅读者。在观察者设计模式的中报社就是主题Subject,阅读者就是Observer,Observer可以向Subject注册或者取消某一事件。Subject维护了一个Observer的List,一旦发现主题变化了,Subject就像Observer更新消息。这就是简单的观察者模式。

    实现这么一个需求:有一个天气的主题,有许多观察者会利用到这些数据,当前显示面板,未来预测面板等。

    设计思路:

    1,声明一个Subject接口,某一个具体的主题都必须实现他,里面主要有三个方法,registerObserver(Observer o),removeObserver(Observer o),notifyObserver(Information info);

   2,声明一个WeatherSubject实现Subject类,实现里面的各种方法,增加一个数据结构ArrayList用来保存Observer信息。

   3,声明一个Observer接口,所有观察者都必须实现这个接口,这个接口只有唯一的update方法,供WeatherObject更新使用。

   4,声明一个CurrentObserver类,这个类实现Observer类,实现update方法

   5,创建一个主函数,创建一个WeatherSubject类,再创建一个CurrentObserver类,然后模拟更新Weather主题。

   那么主题后Observer是如何通信的呢?先声明一个WeatherObject类的时候,然后声明一个CurrentObserver类的时候,在构造函数中向其传递WeatherObject的实例,一遍CurrentObject想其注册。

  -------------------------------------我是分--割------------------------------------------------------------------------------线-------------

以上是我自己写的一个观察者模式的实现,实际上在JAVA的SDK中已经支持观察者模式了,java.utl报中有一个类Observable和Observer这两类,Observable对应Subject,Observer对应观察者,Observerable是一个类,而不是一个接口,这违反了我们尽量使用组合,少用继承的原则,有点问题。它具体使用和我们上面有点不一样,需要先调用setChange,将Ischange变量设置为true,然后notifyObservers才会生效。这是合理的,因为对于温度来说更新速度太快了,十分之摄氏度就会变化,那么Observer将会接收到许许多多的信息,我们希望只在变化达到1度时候才推送这个变化,所以可以通过setChange来实现。

还有一个需要考虑的问题是,Subject推送的这么多消息,某些Observer可能只是需要一些其中的一些属性,所以到底这些变化的消息是推送还是Observer来拉取,这是一个值得考虑的问题,如果是Observer自己来pull,那么必须在subject中实现getter方法的实现,在notifyObservers中就不需要传递变化的消息了,Observer自己来取就好了。

对于采集的信息,可能会变化,所以,当采集的信息变化的时候,Subject也需要变化,Observer中也要变化。

  1 #Subject.java  2 class Information  3 {  4     Information(double d,double e,double f)  5     {  6         this.temp = d;  7         this.max = f;  8         this.min = e;  9     } 10     double temp; 11     double min; 12     double max; 13 } 14  15 public interface Subject { 16    void registerObserver(Observer o); 17    void removeObserver(Observer o); 18    void notifyObservers(Information info); 19 } 20 --------------------- 21 WeatherSubject.java 22 import java.util.ArrayList; 23 import java.util.Iterator; 24 import java.util.List; 25  26  27 public class WeatherSubject implements Subject { 28  29     List<Observer> observer; 30     public WeatherSubject() 31     { 32         observer= new ArrayList<Observer>();//programming to interface; 33     } 34     public  void registerObserver(Observer o) 35     { 36         observer.add(o); 37     } 38     public void removeObserver(Observer o) 39     { 40         int index = observer.indexOf(o); 41         if(index!=-1) 42         { 43             observer.remove(index); 44         } 45     } 46     @Override 47     public void notifyObservers(Information info) { 48         // TODO Auto-generated method stub 49         50         Iterator<Observer> iterator = observer.iterator(); 51         for(;iterator.hasNext();) 52         { 53             iterator.next().update(info); 54         } 55     } 56      57     public void changeInfo(double d,double e,double f) 58     { 59         notifyObservers(new Information(d,e,f)); 60     } 61  62 } 63  64 ---------------------------- 65 Observer.java 66  67 public interface Observer { 68     public void update(Information info); 69 } 70  71 ---------------- 72 Display.java  73 public interface Displayable { 74      public void display(); 75 } 76  77 ------------------- 78 CurrentObserver.java 79  80  81 public class CurrentObserver implements Observer,Displayable { 82  83     double temp,max,min; 84     Subject subject; 85     CurrentObserver(Subject subject) 86     { 87         this.subject = subject; //reserver Subject instance for unregister invoke 88         subject.registerObserver(this); 89     } 90     @Override 91     public void update(Information info) { 92         // TODO Auto-generated method stub 93        temp = info.temp; 94        max = info.max; 95        min = info.min; 96        display(); 97     } 98     public void display() 99     {100         System.out.println("Current: "+temp+" "+max+" "+min);101     }102     103 }104 ------------------105 SubjectMain.java106 107 public class SubjectMain {108 109     /**110      * @param args111      */112     public static void main(String[] args) {113         // TODO Auto-generated method stub114        WeatherSubject weather = new WeatherSubject();115        Observer currentObserver = new CurrentObserver(weather);116        weather.changeInfo(13.3, 16.4, 17.9);117     }118 119 }