气象观测站
你的团队接到一个任务,建立一个能显示气象站数据的应用,可以添加或移除布告板,布告板默认有 目前状况,气象统计,天气预测。用户可以随时添加或移除布告板。提供一个WeatherData对象,可以从气象站获得温度,湿度,气压等信息。
大概长这样
错误的实现
WeatherData类长这样
直接再函数中通知每一个布告板
void WeatherData::measurementsChanged(){
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
//通知每一个布告板
bgb1.updata(temp,humidity,pressure);
bgb2.updata(temp,humidity,pressure);
bgb3.updata(temp,humidity,pressure);
}
有哪些不妥
- 我们是针对实现编程,而不是针对接口。
- 对于每一个布告板,我们都要修改代码
- 我们无法动态的增加或删除布告板
。。。
使用观察者模式
出版者 + 订阅者 = 观察者模式
设计好出题和观察者的抽象基类,让WeatherData继承主题,布告板继承观察者。实现方式有很多,一种是Subject维护一个Observer对象的数组
class Observer{
virtual void update(float temp,float humidity,float pressure)=0;
};
class Subject{
public:
virtual void registerObserver(Observer * po)=0;
virtual void removeObserver(Observer * po)=0;
virtual void notifyObservers()=0;
protected:
vector oblist;
};
具体实现
WeatherData
class WeatherData:public Subject{
public:
virtual void registerObserver(Observer * po);
virtual void removeObserver(Observer * po);
virtual void notifyObservers();
void setdata(float t,float h,float p);
private:
float temperature;
float humidity;
float pressure;
};
void WeatherData::registerObserver(Observer * po){
oblist.push_back(po);
}
void WeatherData::removeObserver(Observer * po){
int i;
for(i=0;iupdate(temperature,humidity,pressure);
}
}
void WeatherData::setdata(float t,float h,float p){
temperature=t;
humidity=h;
pressure=p;
notifyObservers();
}
布告板
class Bgb:public Observer{//布告板
public:
virtual void update(float temp,float humidity,float pressure);
void display();//打印
private:
float t,h,p;//存放接受数据
};
void Bgb::update(float temp,float humidity,float pressure){
t=temp; h=humidity; p=pressure;
}
void Bgb::display(){
cout<<"Bjb * is"<<(int *)(this) <
完整测试代码
#include
#include
using namespace std;
class Observer{
public:
virtual void update(float temp,float humidity,float pressure)=0;
};
class Subject{
public:
virtual void registerObserver(Observer * po)=0;
virtual void removeObserver(Observer * po)=0;
virtual void notifyObservers()=0;
protected:
vector oblist;
};
//----------------------------------------------------------
class WeatherData:public Subject{
public:
virtual void registerObserver(Observer * po);
virtual void removeObserver(Observer * po);
virtual void notifyObservers();
void setdata(float t,float h,float p);
private:
float temperature;
float humidity;
float pressure;
};
class Bgb:public Observer{//布告板
public:
virtual void update(float temp,float humidity,float pressure);
void display();//打印
private:
float t,h,p;//存放接受数据
};
//----------------------------------------------------------
int main(){
WeatherData WD; //一个主题
Bgb bjb1,bjb2,bjb3; //三个观察者
WD.registerObserver(&bjb1);//注册
WD.registerObserver(&bjb2);
WD.registerObserver(&bjb3);
WD.setdata(1,2,3);
bjb1.display();//打印每个观察者得到的信息
bjb2.display();
bjb3.display();
cout<update(temperature,humidity,pressure);
}
}
void WeatherData::setdata(float t,float h,float p){
temperature=t;
humidity=h;
pressure=p;
notifyObservers();
}
程序输出
首先3个布告板都订阅,更新数据 1 2 3
然后布告板3取消订阅
更新数据 8 9 10
只有bgb3没有收到
观察者模式
定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。