C++观察者模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shineboyxxb/article/details/52141384

最近在看《headfirst 设计模式》这本书,里面讲的设计模式是基于java语言的,看完后我会利用C++来实现以加深自己的理解。先呈上观察者模式:

观察者模式定义了对象间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。它主要包括了一个主题和若干个观察者,只要一个对象注册成为观察者,主题状态改变时,这个对象就能收到通知。模型如下:


这里借用了《headfirst 设计模式》的介绍,C++里面没有接口,但是C++支持多重继承,所以可以用抽象类来代替接口;代码实现如下:

#include "stdafx.h"
#include <iostream>
#include <list>
#include <iomanip>
using namespace std;
class Observer
{
public:
	virtual void update(float tmp,float humidity,float pressure)=0;
};
class Subject
{
public:
	virtual void registerObserver(Observer* o)=0;
	virtual void removeObserver(Observer* o)=0;
	virtual void notifyObservers()=0;
};

class WeatherData :public Subject
{
public:
	void registerObserver(Observer* o)
	{
		observeList.push_back(o);
	}
	void removeObserver(Observer* o)
	{
		observeList.remove(o);
	}
	void notifyObservers()
	{
		for (list<Observer*>::iterator it=observeList.begin();it!=observeList.end();++it)
		{
			(*it)->update(temprature,humidity,pressure);
		}
	}
	void measurementsChanged()
	{
		notifyObservers();
	}
	void setMeasurements(float temprature,float humidity,float pressure)
	{
		this->temprature=temprature;
		this->humidity=humidity;
		this->pressure=pressure;
		measurementsChanged();
	}
private:
	float temprature;
	float humidity;
	float pressure;
	list<Observer*> observeList;
};

class CurrentConditonDisplay:public Observer
{
public:
	CurrentConditonDisplay(Subject *weatherdata)
	{
		this->myWeatherData=weatherdata;
		Subscribe();
	}
	void update(float tmp,float humidity,float pressure)
	{
		this->temprature=tmp;
		this->humidity=humidity;
		display();
	}
    void display()
	{
		cout<<"Current Condition: "<<setprecision(3)<<showpoint<<temprature<<"F degree and "<<setprecision(3)<<humidity<<"% humidity"<<endl;
	}
	void Subscribe()
	{
		myWeatherData->registerObserver(this);
	}
	void Unsubscribe()
	{
		myWeatherData->removeObserver(this);
	}
private:
	float temprature;
	float humidity;
        Subject *myWeatherData;

};

class StatisticDisplay:public Observer
{
public:
	StatisticDisplay(Subject *weatherdata)
	{
		this->myWeatherData=weatherdata;
		Subscribe();
		this->maxTemprature=-1000;
		this->minTemprature=1000;
	}
	void update(float tmp,float humidity,float pressure)
	{
		this->minTemprature=min(minTemprature,tmp);
		this->maxTemprature=max(maxTemprature,tmp);
		
		display();
	}
	void display()
	{
		cout<<"Max/Min Temperature= "<<setprecision(3)<<showpoint<<maxTemprature<<"/"<<setprecision(3)<<minTemprature<<endl;
	}
	void Subscribe()
	{
		myWeatherData->registerObserver(this);
	}
	void Unsubscribe()
	{
		myWeatherData->removeObserver(this);
	}
private:
	float minTemprature;
	float maxTemprature;
	Subject *myWeatherData;

};
int _tmain(int argc, _TCHAR* argv[])
{
	WeatherData *myWeatherData=new WeatherData;
	CurrentConditonDisplay conditionDisplay(myWeatherData);  //默认成为观察者

	StatisticDisplay statisticDisplay(myWeatherData);      //默认成为观察者

	myWeatherData->setMeasurements(80,65,30.4f);
	myWeatherData->setMeasurements(82,70,29.2f);

	conditionDisplay.Unsubscribe();         //取消订阅,不再是观察者
	myWeatherData->setMeasurements(78,90,29.2f);
	delete myWeatherData;
	return 0;
}
运行结果如下:




猜你喜欢

转载自blog.csdn.net/shineboyxxb/article/details/52141384
今日推荐