现在的位置: 首页 > 综合 > 正文

观察者模式observer

2013年10月12日 ⁄ 综合 ⁄ 共 2453字 ⁄ 字号 评论关闭

有一个subject, 一群observer, subject的实例保存了observer的列表,当发生改变的时候可以通知observer进行update。

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

class Observer
{
public:
	virtual void update(float temp, float humidity, float pressure)
	{
	}

	bool operator == (const Observer* o1)
	{
		return o1 == this;
	}
};

class DisplayElement
{
public:
	virtual void display()
	{

	}
};

class Subject
{
public:
	virtual void registerObserver(Observer* o) = 0;
	virtual void removeObserver(Observer* o) = 0;
	virtual void notifyObservers() = 0;
};

class WeatherData : public Subject
{
private:
	list<Observer*>* observers;
	float temperature;
	float humidity;
	float pressure;

public:
	WeatherData()
	{
		observers =  new list<Observer*>();
	}
	
	virtual void registerObserver(Observer* o)
	{
		observers->push_back(o);
	}

	virtual void removeObserver(Observer* o)
	{
		observers->remove(o);
	}
	virtual void notifyObservers()
	{
		for(list<Observer*>::iterator it = observers->begin() ; it != observers->end(); ++it)
		{
			(*it)->update(temperature, humidity, pressure);
		}
	}
	void measurementsChanged()
	{
		notifyObservers();
	}

	void setMeasurements(float temperature, float humidity, float pressure)
	{
		this->temperature = temperature;
		this->humidity = humidity;
		this->pressure = pressure;
		measurementsChanged();
	}
};

class CurrentConditionDisplay : public Observer, public DisplayElement
{
private:
	float temperature;
	float humidity;
	WeatherData weatherData;

public:
	CurrentConditionDisplay(WeatherData weatherData)
	{
		this->weatherData = weatherData;
		weatherData.registerObserver(this);
	}

	virtual void update(float temperature, float humidity, float pressure)
	{
		this->temperature = temperature;
		this->humidity = humidity;
		display();
	}
	virtual void  display()
	{
		cout<<"current conditions: " << temperature << " F degrees and " << humidity <<"%humidity"<<endl;
	}
};

int main()
{
	WeatherData* weatherData = new WeatherData();
	CurrentConditionDisplay* currentDisplay = new CurrentConditionDisplay(*weatherData);
	CurrentConditionDisplay* currentDisplay2 = new CurrentConditionDisplay(*weatherData);
	weatherData->setMeasurements(80, 65, 30.4f);
	weatherData->setMeasurements(82, 70, 29.2f);
	weatherData->removeObserver(currentDisplay2);
	weatherData->setMeasurements(78, 90, 29.2f);
}

按惯例记录将代码用c++重写遇到的问题。

1. 抽象类不能有实例。 所以如果需要实例,只好避免使用纯虚函数,而改为在函数里不写代码。

2. list的应用时候由于这个是定义类型,且remove需要使用==来判断是否删除,这时候需要在observer对==进行运算符重载。

3. 在本例中直接保存对象到list,在比较的时候会比较麻烦,所以采用保存observer的指针到list,比较时候采用的是比较指针指向的地址是否相同。本对象的指针其实就是this。

4. 之所以把observers设置为指针是因为new list返回的是指针类型。而如果将observers =  new list<Observer*>(); 写成observers =   list<Observer*>(); 编译能通过但是会出现list iterator not dereferencable。 应该是new与不new上有区别。

5. 由于原java程序中,接口很多,所以在c++实现的过程中不可避免的要用到多重继承,在更复杂的情况在还可能需要用到虚基类。不知道是否有更好的方法来替代java中的接口。

抱歉!评论已关闭.