C++设计模式--观察者模式

本文详细介绍并演示了使用C++实现观察者模式的过程。通过天气数据与当前条件显示的例子,展示了主题对象如何注册、通知观察者,并更新状态。主题对象(WeatherData)与观察者对象(CurrentConditionsDisplay)的代码实现,以及主函数中每秒更新主题状态的循环,共同构成了一个动态的观察者模式实例。

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

                                                                                                                                                   --《Head First》设计模式

 

                             

                                                                             图片来自网络

 

C++实现观察者模式:

主题对象:

//weatherdata.h
#ifndef __WEATHERDATA_H__
#define __WEATHERDATA_H__

#include <list>
#include "currentconditionsdisplay.h"

class Observer;

//主题对象,负责注册,删除,通知观测者
class Subject
{
public:
    Subject();
    ~Subject();
    virtual void RegisterObserver(Observer* o);
    virtual void RemoveObserver(Observer* o);
    virtual void NotifyObserver();
};


class WeatherData : public Subject
{

public:
    WeatherData();
    virtual ~WeatherData();
    void setMeasurements(float temperature,float humidity,float pressure);

public:
    virtual void RegisterObserver(Observer* o) override;
    virtual void RemoveObserver(Observer* o) override;
    virtual void NotifyObserver() override;

private:
    void MeasurementsChanged();
private:
    std::list<Observer*> observers;
    float m_temperature;
    float m_humidity;
    float m_pressure;
};
#endif

主题对象实现:

//weatherdata.cc
#include "weatherdata.h"

Subject::Subject()
{
}

Subject::~Subject()
{
}

void Subject::RegisterObserver(Observer* o)
{
}

void Subject::RemoveObserver(Observer* o)
{
}

void Subject::NotifyObserver()
{
}

WeatherData::WeatherData():Subject()
{
}

WeatherData::~WeatherData()
{
}

void WeatherData::RegisterObserver(Observer* o)
{
    if (o)
        observers.push_back(o);
}
void WeatherData::RemoveObserver(Observer* o)
{
    if (o)
        observers.remove(o);
}

void WeatherData::NotifyObserver()
{
    for (auto x : observers)
        x->Update(m_temperature,m_humidity,m_pressure);
}

void WeatherData::setMeasurements(float temperature,
                            float humidity,float pressure)
{
    m_temperature = temperature;
    m_humidity = humidity;
    m_pressure = pressure;
    //通知观察者
    MeasurementsChanged();
}

void WeatherData::MeasurementsChanged()
{
    NotifyObserver();
}

 

观察者对象:

//currentconditionsdisplay.h
#ifndef __CURRENTCONDITIONSDISPLAY_H__
#define __CURRENTCONDITIONSDISPLAY_H__

#include "weatherdata.h"

class Subject;

class Observer
{
public:
    Observer();
    virtual void Update(float temperature,
                            float humidity,float pressure);
};


class CurrentConditionsDisplay : public Observer
{
public:
    CurrentConditionsDisplay(Subject* subject);
    virtual void Update(float temperature,
                                float humidity,float pressure);

private:
    void display();

private:
    float m_temperature;
    float m_humidity;
    float m_pressure;

    Subject* m_subject;
};

#endif
//currentconditionsdisplay.cc
#include <iostream>
#include "currentconditionsdisplay.h"

Observer::Observer()
{
}

void Observer::Update(float temperature,
                            float humidity,float pressure)
{
}

CurrentConditionsDisplay
        ::CurrentConditionsDisplay(Subject* subject)
        :m_subject(subject)
{
    m_subject->RegisterObserver(this);
}

void CurrentConditionsDisplay::Update(float temperature,
                                float humidity,float pressure)
{
    m_temperature = temperature;
    m_humidity = humidity;
    m_pressure = pressure;
    
    display();
}

void CurrentConditionsDisplay::display()
{
    std::cout << "CurrentConditions : (temperature : " << m_temperature
         << "),(humidity : " << m_humidity << "),(pressure : "<<m_pressure
         <<")"<<std::endl;
}

 

主函数:

//main.cc
#include <unistd.h>

#include "weatherdata.h"
#include "currentconditionsdisplay.h"

int main()
{
    WeatherData weatherData;
    CurrentConditionsDisplay currentConditionsDisplay(&weatherData);
    float temperature = 25.5;
    float humidity = 85;
    float pressure = 20;
    while(true){
        weatherData.setMeasurements(temperature++,humidity--,pressure++);
        sleep(1);
    }
    return 0;
}

 

主函数每隔1秒修改一次主题对象,主题对象更新后通知观察者。

Linux下编译:

g++ -std=c++11 -o main main.cc currentconditionsdisplay.cc weatherdata.cc
./main

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值