Posted on 2008-06-09 15:32
阿呆 阅读(299)
评论(0) 编辑 收藏 引用 所属分类:
设计模式学习笔记
出版者+订阅者=观察者模式
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新(回调函数)。
主题(Subject)是真正拥有数据的人,观察者是主题的依赖者,在数据变化时更新,这样比起让许多对象控制同一份数据来,可以得到更干净的OO设计。
定义观察者模式:
当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主体和观察者之间松耦合。
改变主体或者观察者的一方,并不会影响另一方,因为两者是松耦合的,所以,只要他们之间的接口仍被遵守,我们就可以自由的改变他们。
设计原则:为了交互对象之间的松耦合设计而努力。
气象站类图:
DefInterface.h:
1#ifndef DEFINTERFACE_H__
2#define DEFINTERFACE_H__
3
4//-------interface definition begin---------------------------------------
5class Observer
6{
7public:
8 virtual void Update(float temp, float humidity, float pressure){}
9};
10
11
12class DisplayElement
13{
14public:
15 virtual void Display(){}
16};
17
18class Subject
19{
20public:
21 virtual void RegisterObserver(Observer* o){}
22 virtual void RemoveObserver(Observer* o){}
23 virtual void NotifyObserver(){}
24};
25//-------interface definition End-----------------------------------------
26
27#endif
DisplayBoard.h:
1#ifndef __DISPLAYBOARD_H__
2#define __DISPLAYBOARD_H__
3#include "DefInterface.h"
4class CurrentConditionDisplay : public Observer, public DisplayElement
5{
6public:
7 CurrentConditionDisplay(Subject* weatherdata);
8 ~CurrentConditionDisplay();
9 void Update(float temp, float humidity, float pressure);
10 void Display();
11protected:
12private:
13 float m_tempt;
14 float m_hum;
15 float m_pres;
16 Subject* m_weatherData;
17};
18
19#endif
DisplayBoard.cpp:
1#include "stdafx.h"
2#include "DisplayBoard.h"
3#include <iostream>
4using namespace std;
5
6CurrentConditionDisplay::CurrentConditionDisplay(Subject* weatherdata)
7:m_weatherData(weatherdata), m_hum(0.0F), m_pres(0.0F), m_tempt(0.0F)
8{
9 m_weatherData->RegisterObserver(this);
10}
11
12CurrentConditionDisplay::~CurrentConditionDisplay()
13{
14
15 m_weatherData->RemoveObserver(this);
16 delete m_weatherData;
17
18};
19void CurrentConditionDisplay::Update(float temp, float humidity, float pressure)
20{
21 m_tempt = temp;
22 m_hum = humidity;
23 m_pres = pressure;
24 Display();
25}
26void CurrentConditionDisplay::Display()
27{
28 cout << "Current temperature:" << m_tempt << endl;
29 cout << "Current humidity:" << m_hum << endl;
30 cout << "Current pressure:" << m_pres << endl;
31
32}
WeatherStation.h:
1#ifndef __SUBJECT_H__
2#define __SUBJECT_H__
3
4#include <afxtempl.h>
5#include "DefInterface.h"
6//-------concrete class definition begin----------------------------------
7class WeatherData : public Subject
8{
9public:
10 WeatherData();
11 ~WeatherData();
12 void RegisterObserver(Observer* o);
13 void RemoveObserver(Observer* o);
14 void NotifyObservers();
15
16 float GetTemprature();
17 float GetHumidity();
18 float GetPressure();
19 void MeasurementsChanged();
20 void SetMeasurements(float temp, float humidity, float pressure);
21private:
22 CArray<Observer*> m_observers;
23 float m_temperature;
24 float m_humidity;
25 float m_pressure;
26};
27//-------concrete class definition End------------------------------------
28#endif
WeatherStation.cpp:
1#include "stdafx.h"
2#include "WeatherStation.h"
3
4WeatherData::WeatherData():m_humidity(0.0F), m_pressure(0.0F), m_temperature(0.0F)/**//*,m_observers(NULL)*/
5{
6 //m_observers = new CArray();
7}
8
9WeatherData::~WeatherData()
10{
11 m_observers.RemoveAll();
12}
13void WeatherData::RegisterObserver(Observer* o)
14{
15 m_observers.Add(o);
16}
17
18void WeatherData::RemoveObserver(Observer* o)
19{
20 int icount = m_observers.GetCount();
21 for (int i = 0; i < icount; i++)
22 {
23 if (m_observers[i] == o)
24 {
25 m_observers.RemoveAt(i);
26 }
27 }
28}
29
30void WeatherData::NotifyObservers()
31{
32 int icount = m_observers.GetCount();
33 for (int i = 0; i < icount; i++)
34 {
35 Observer* observer = m_observers[i];
36 observer->Update(m_temperature, m_humidity, m_pressure);
37 }
38}
39
40float WeatherData::GetTemprature()
41{
42 return m_temperature;
43}
44float WeatherData::GetHumidity()
45{
46 return m_humidity;
47}
48float WeatherData::GetPressure()
49{
50 return m_pressure;
51}
52
53void WeatherData::MeasurementsChanged()
54{
55 NotifyObservers();
56}
57
58void WeatherData::SetMeasurements(float temp, float humidity, float pressure)
59{
60 m_temperature = temp;
61 m_humidity = humidity;
62 m_pressure = pressure;
63 MeasurementsChanged();
64}
65
66
Test.cpp:
1// WeatherStation_ObserverPatten.cpp : Defines the entry point for the console application.
2//
3
4#include "stdafx.h"
5#include "WeatherStation.h"
6#include "DisplayBoard.h"
7
8int _tmain(int argc, _TCHAR* argv[])
9{
10 WeatherData* wd = new WeatherData();
11 CurrentConditionDisplay* board = new CurrentConditionDisplay(wd);
12 wd->SetMeasurements(35.4, 20, 100);
13 wd->RemoveObserver(board);
14 CurrentConditionDisplay cur(wd);
15 wd->SetMeasurements(35.4, 20, 10);
16
17
18 return 0;
19}
20
21