10 观察者模式

老板回来,我不知道——观察者模式

观察者模式,又叫发布-订阅(Publish/Subscribe)模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主体对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

“当一个对象的改变需要同时改变其他对象时使用此模式。”

“而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。”
“总的来讲,观察者模式所作的工作其实就是在解除耦合。让耦合的双方都依赖于抽象而不是依赖于具体。从而使得各自的变换都不会影响另一边的变化。”

代码
1 //main.cpp
2  #include "Boss.h"
3 #include "Observer.h"
4 #include "StockObserver.h"
5 #include "Subject.h"
6 #include "NBAObserver.h"
7
8  int main()
9 {
10 //老板胡汉三
11   Boss *huhansan = new Boss();
12
13 //看股票的同事
14 StockObserver *tongshi1 = new StockObserver("小魏", huhansan);
15 //看NBA的同事
16 NBAObserver *tongshi2 = new NBAObserver("小易", huhansan);
17
18 huhansan->Attach(tongshi1);
19 huhansan->Attach(tongshi2);
20
21 huhansan->Detach(tongshi1);
22
23 //老板回来
24 huhansan->action = "我胡汉三回来了!";
25 //发出通知
26 huhansan->Notify();
27
28 return 0;
29 };
30
31 //Subject.h
32 #include <string>
33
34 using namespace std;
35
36 class Observer;
37
38 #ifndef SUBJECT_H_H
39 #define SUBJECT_H_H
40
41 class Subject
42 {
43 public:
44 virtual void Attach(Observer *observer){}
45 virtual void Detach(Observer *observer){}
46 virtual void Notify(){}
47 public:
48 string action;
49 };
50
51 #endif
52
53 //Boss.h
54 #include <list>
55 #include "Subject.h"
56 using namespace std;
57
58 class Observer;
59
60 #ifndef BOSS_H_H
61 #define BOSS_H_H
62
63 class Boss : public Subject
64 {
65 public:
66 void Attach(Observer *observer);
67 void Detach(Observer *observer);
68 void Notify();
69
70 private:
71 list<Observer*> observers; //此处保存的是指针
72
73 };
74
75 #endif
76
77 //Observer.h
78 #include <string>
79 using namespace std;
80
81 class Subject;
82
83 #ifndef OBSERVER_H_H
84 #define OBSERVER_H_H
85
86 //抽象的观察者
87 class Observer
88 {
89 public:
90 Observer(){}
91 Observer(string name, Subject *sub);
92 virtual void Update(){}
93
94 public:
95 string name;
96 Subject *sub;
97
98 };
99
100 #endif
101
102 //StockObserver.h
103 #include "Observer.h"
104
105 class Observer;
106
107 #ifndef STOCKOBSERVER_H_H
108 #define STOCKOBSERVER_H_H
109
110 //看股票的同事
111 class StockObserver : public Observer
112 {
113 public:
114 StockObserver(string name, Subject *sub);
115 virtual void Update();
116 };
117
118 #endif
119
120 //NBAObserver.h
121 #include "Observer.h"
122
123 class Observer;
124
125 #ifndef NBAOBSERVER_H_H
126 #define NBAOBSERVER_H_H
127
128 //看股票的同事
129 class NBAObserver : public Observer
130 {
131 public:
132 NBAObserver(string name, Subject *sub);
133 virtual void Update();
134 };
135
136 #endif
137
138 //Observer.cpp
139 #include "observer.h"
140 #include "Subject.h"
141
142 Observer::Observer(string name, Subject *sub)
143 {
144 this->name = name;
145 this->sub = sub;
146 }
147
148 //Boss.cpp
149 #include "boss.h"
150 #include "observer.h"
151 #include <iostream>
152 using namespace std;
153
154 void Boss::Attach(Observer *observer)
155 {
156 observers.push_back(observer);
157 }
158
159 void Boss::Detach(Observer *observer)
160 {
161 for(list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
162 {
163 if((*iter)->name == observer->name)
164 {
165 observers.erase(iter);
166 break;
167 }
168 }
169 }
170
171 void Boss::Notify()
172 {
173 cout<<action<<endl;
174 for(list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
175 {
176 (*iter)->Update();//通知所有观察者更新状态
177 }
178 }
179
180 //StockObserver.cpp
181 #include "stockobserver.h"
182 #include "Observer.h"
183 #include "Subject.h"
184
185 #include <iostream>
186
187 using namespace std;
188
189 StockObserver::StockObserver(string name, Subject *sub)
190 {
191 Observer(name, sub);
192 //this->name = name;
193 //this->sub = sub;
194 }
195
196 void StockObserver::Update()
197 {
198 //cout<<sub->action<<" "<<name<<" 关闭股票行情,继续工作!"<<endl;
199 cout<<name<<" 关闭股票行情,继续工作!"<<endl;
200 }
201
202 //NBAObserver.cpp
203 #include "nbaobserver.h"
204 #include "Observer.h"
205 #include "Subject.h"
206
207 #include <iostream>
208
209 NBAObserver::NBAObserver(string name, Subject *sub)
210 {
211 Observer(name, sub);
212 //this->name = name;
213 //this->sub = sub;
214 }
215
216 void NBAObserver::Update()
217 {
218 //cout<<sub->action<<" "<<name<<" 关闭NBA直播,继续工作!"<<endl;
219 cout<<name<<" 关闭NBA直播,继续工作!"<<endl;
220 }

 

 

 

posted @ 2010-05-24 15:58  斯芬克斯  阅读(335)  评论(3编辑  收藏  举报