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