观察者模式定义:对象之间的一对多的依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
我们可以独立复用主题主题或者观察者。如果我们在其他地方需要使用主题或者观察者,可以轻易地复用,因为二者并非耦合。
设计原则:为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。
以上都是看Headfirst上面的一些觉得对自己有用的概念。
----------------------C++代码--------------------------------------------------------------------------------------------------------------
在代码贴之前说明一下,关于JAVA实现的观察者模式,如果应用到C++上,会改变Subject接口,使其成为类,个人感觉这样并不是很顺,如果要满足push或者pull的方法,可以在Subject接口中定义几个Get纯虚函数在WeatherData中实现即可。下面是没有实现pull仅仅是push的实现。
#include<iostream>
#include <list>
using namespace std;
class Observer
{
public:
virtual void update(float temp,float humidity,float pressure)=0;
};
class DisplayElement
{
public:
virtual void display()=0;
};
class Subject
{
public:
virtual void RegisterObserver(Observer *o)=0;//纯虚函数的访问必须是定义一个指针对象,否则出错编译
virtual void RemoveObserver(Observer *o)=0;
virtual void NotifyObeserver()=0;
};
class WeatherData:public Subject
{
private:
list<Observer*> observer;//这也是为什么要定义list类型为指针类型,因为要根据纯虚函数实现多态。
float temperature;
float humidity;
float pressure;
public:
WeatherData()
{
}
virtual ~WeatherData()
{
}
void RegisterObserver(Observer* o)
{
observer.push_back(o);
}
void RemoveObserver(Observer* o)
{
observer.remove(o);
}
void NotifyObeserver()
{
list<Observer*>::iterator it=observer.begin();
for (;it!=observer.end();++it)
{
(*it)->update(temperature,humidity,pressure);
}
}
void measurementsChanged()
{
NotifyObeserver();
}
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 temperture;
float humidity;
Subject* weatherDate;
public:
CurrentConditionDisplay(Subject* weatherDate)
{
this->weatherDate=weatherDate;
weatherDate->RegisterObserver(this);
//weatherDate->RemoveObserver(this);
}
void update(float temp,float humidity,float pressure)
{
this->temperture=temp;
this->humidity=humidity;
display();
}
void display()
{
cout<<"Current Condition: "<<temperture<<"F degress and humidity %"<<humidity<<endl;
}
};
class StatisticsDisplay:public Observer,public DisplayElement
{
private:
float temperture;
float humidity;
float pressure;
Subject* weatherDate;
public:
StatisticsDisplay(Subject* weatherDate)
{
this->weatherDate=weatherDate;
weatherDate->RegisterObserver(this);
}
void update(float temp,float humidity,float pressure)
{
this->temperture=temp;
this->humidity=humidity;
this->pressure=pressure;
display();
}
void display()
{
cout<<"StatisticsDisplay: "<<temperture<<"F degress "<<"and pressure "<<pressure<<" and humidity %"<<humidity<<endl;
}
};
int main()
{
WeatherData *weatherDate=new WeatherData();
CurrentConditionDisplay *currentDisplay=new CurrentConditionDisplay(weatherDate);//此处为了实际传入weatherDate来调用类weather而用
StatisticsDisplay *statisticsDisplay=new StatisticsDisplay(weatherDate);
weatherDate->setMeasurements(80,65,30.4f);
weatherDate->setMeasurements(82,70,29.2f);
weatherDate->setMeasurements(78,90,29.2f);
delete weatherDate;
delete currentDisplay;
delete statisticsDisplay;
return 0;
}