【软件编程】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
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
signature:
-------------------------------------------------------------------
向着理想进军!因为我是Vincent【象征着征服与执着】