首页 > 代码库 > 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 }