【软件编程】Observer观察者模式

      设计模式之 观察者模式

观察者模式有很多形式,比较直观的一种是使用一种“注册—通知—撒销通知”的形式。

1.观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器里。

2.被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。

3.观察者告诉被观察者要撒销观察,被观察者从容器中将观察者去除。

关键字:

  在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

方法:

 可自己实现观察者模式,也可利用JDK内置的支持实现。这个比较简单:

被观察者:java.util.Observable类

观察者:java.util.Observer接口

 

我们来举几个例子。

被观察者:猫

观察者:老鼠、主人

猫一叫,老鼠四串,主人惊醒

 

被观察者:前台秘书

观察者:办公室爱看NBA的小张、爱看网路小说的小李

前台秘书通知老板来了,小张关掉NBA,小李关掉小说。

 

被观察者:美眉

观察者:追求她的小王,爱慕她的小刘

美眉一有新动态,小王通过短信知道,小刘通过电话知道。

 

观察者:地球

被观察者:天气预报中心,普通人

天气一变化,中心就开始报到,人也感觉到了

下面就对最后一个例子,做一下详细的代码分析。

【 定义被观察者为地球,而观察者可以有不同方式,可以是天气预报中心也可以是我们普通人。只要是被观察者地球的天气一发生变化,就会通知所有注册它的观察者,做出相应的响应。

 

  1 package mode;
  2 import java.util.Observable; 
  3 import java.util.Observer; 
  4 
  5 /**
  6  *  被观察对象:地球 
  7  */   
  8 //------------被观察者-------------------
  9 class Earth extends Observable 
 10 {
 11     private String weather = "晴朗"
 12 
 13     public String getWeather()  
 14     { 
 15         return weather; 
 16     }   
 17 
 18     public void setWeather(String weather)
 19     { 
 20         //        设置变化点  
 21         this.weather = weather; 
 22         
 23                 /*     在Observable类中。
 24                     protected void setChanged()
 25                     标记此 Observable 对象为已改变的对象;
 26                     现在程序自动调用 hasChanged 方法,并且将返回 true。 
 27                    
 28                  *     
 29                  *     在Observable类中。
 30                       介绍一下hasChanged()
 31                     public boolean hasChanged()
 32                     测试对象是否改变。 
 33                     返回:当且仅当在此对象上最近调用了 setChanged 方法,
 34                     而不是 clearChanged 方法时,才返回 true;否则返回 false。
 35                  */ 
 36         
 37         setChanged(); 
 38         
 39                 /*
 40                  *  public void notifyObservers()[重载]
 41                     public void notifyObservers(Object arg)
 42                     如果 hasChanged 方法指示对象已改变,则通知其所有观察者,
 43                     并自动调用 clearChanged 方法来指示此对象不再改变。也就是说,返回false。
 44                  */
 45         
 46         notifyObservers(weather); //将改变的消息通知所有观察者。
 47         /*
 48          * 应用程序调用 Observable 对象的 notifyObservers 方法,以便向所有该对象的观察者通知此改变。 
 49          * 在Observer中有每个观察者都有其 update 方法,
 50          * 只要改变了 observable 对象就自动调用update方法。
 51          * 其调用参数有两个:observable 对象和 arg 参数。
 52          * */
 53     }   
 54 }   
 55 /*
 56  * [注意]  在需检测的对象前需要设置变化点setChanged()和通知观察者notifyObservers(),这两个函数是由Observable类实现的,封装了观察者模式实现的细节。 
 57 
 58     观察者:气象卫星(Satellite) 
 59  */ 
 60 
 61 
 62 
 63 /** 
 64  *  观察对象:气象卫星 
 65  */   
 66   //-------------观察者1-----------------
 67 class Satellite implements Observer 
 68 
 69     private String  weather; 
 70 
 71     //将被观察者earth对象,和天气信息传给每一个观察者。
 72     public void update(Observable  obj,  Object  arg)      
 73     { 
 74         weather = (String)  arg; 
 75 
 76         //    捕获天气变化情况,反馈给检测者   
 77         System.out.println(  "  近期天气变化:  "  +  weather); 
 78     }   
 79 }   
 80 
 81 /** 
 82  *  观察对象:普通人 
 83  */ 
 84 //-------------观察者2-----------------
 85 class People implements Observer 
 86 
 87     private String  weather; 
 88 
 89     //将被观察者earth对象,和天气信息传给每一个观察者。
 90     public void update(Observable  obj,  Object  arg)      
 91     { 
 92         weather = (String)  arg; 
 93 
 94         //    捕获天气变化情况,反馈给检测者   
 95         System.out.println(  "  我感觉:  "  +  weather); 
 96     }   
 97 }   
 98 
 99 
100 
101 //客户端调用:气象局(WeatherService)   
102 
103 /** 
104  *  客户端调用:天气预报 
105  *   
106  */   
107 public class ObserverMain     
108 
109     public static void main(String[]  args)   
110     { 
111         Earth  earth  =  new Earth();           //创建被观察者 
112         Satellite  satellite  =new Satellite(); //观察者1
113         People  people  =new People();          //观察者2
114          //在被观察对象中注册观察者 如果观察者与集合中已有的观察者不同,则向对象的观察者集合中添加此观察者。
115         earth.addObserver(satellite); 
116         earth.addObserver(people);
117 
118         System.out.println(  "  天气预报:  "  ); 
119 
120         System.out.println(  "  ---------------------------  "  ); 
121         earth.setWeather(  "  台风‘珍珠’逼近  "  ); 
122         earth.setWeather(  "  大到暴雨  "  ); 
123         
124         earth.deleteObserver(people);//从对象的观察者集合中删除某个观察者。
125         
126         earth.setWeather(  "  天气炎热  "  ); 
127     }   
128 }   
129 
130 
posted @ 2008-09-26 00:00  蒋琦  阅读(345)  评论(1编辑  收藏  举报