观察者模式observer

来源:互联网 发布:java时间戳加减 编辑:程序博客网 时间:2024/06/05 19:24

有一个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中的接口。