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.java
106 
107 public class SubjectMain {
108 
109     /**
110      * @param args
111      */
112     public static void main(String[] args) {
113         // TODO Auto-generated method stub
114        WeatherSubject weather = new WeatherSubject();
115        Observer currentObserver = new CurrentObserver(weather);
116        weather.changeInfo(13.3, 16.4, 17.9);
117     }
118 
119 }
原文地址:https://www.cnblogs.com/championlai/p/3815098.html