posts - 7, comments - 5, trackbacks - 0, articles - 4

HeadFirst学习笔记2-观察者模式

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.420100);
13     wd->RemoveObserver(board);
14     CurrentConditionDisplay cur(wd);
15     wd->SetMeasurements(35.42010);
16     
17
18    return 0;
19}

20
21


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理