观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。
模仿书中代码、、
//观察者模式
#include <iostream>
using namespace std;
#include<vector>
class Observer;
class Subject{
public:
virtual void registerObserver( Observer &o ){};
virtual void removeObserver( Observer &o ){};
virtual void notifyObserves(){};
};
class Observer{
int id;
public:
virtual void update(float temp, float humidity, float pressure)
{};
void set_id( int id )
{
this->id = id;
}
int get_id(){
return id;
}
};
class DisplayElement{
public:
virtual void display(){};
};
class WeatherData:public Subject{
vector<Observer *> observers;
float temperature;
float humidity;
float pressure;
public:
void registerObserver( Observer &o )
{
observers.push_back( &o );
o.set_id( observers.size() );
}
void removeObserver( Observer &o )
{
observers.erase( observers.begin() + o.get_id() - 1 );
}
void notifyObservers()
{
for( int i = 0; i < observers.size(); ++i )
{
Observer *observer = observers[i];
observer->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 CurrentConditionsDisplay: public Observer, public DisplayElement{
float temperature;
float humidity;
Subject weatherData;
public:
CurrentConditionsDisplay( Subject &weatherData )
{
this->weatherData = weatherData;
weatherData.registerObserver(*this);
}
virtual void update( float temperature, float humidity, float pressure )
{
this->temperature = temperature;
this->humidity = humidity;
display();
}
void display()
{
cout.setf( ios::fixed );
cout.precision(1);
cout<<"Current conditions: "<<temperature<<"F degrees and "<<humidity<<"% humidity"<<endl;
}
};
void test()
{
WeatherData *weatherData = new WeatherData();
CurrentConditionsDisplay *currentDisplay =
new CurrentConditionsDisplay( *weatherData );
weatherData->setMeasurements( 80, 65, 30.4f );
weatherData->removeObserver( *currentDisplay );
weatherData->setMeasurements( 82, 70, 29.2f );
weatherData->registerObserver( *currentDisplay );
weatherData->setMeasurements( 78, 90, 29.2f );
}
int main()
{
test();
return 0;
};