我们先看看报社和杂志的订阅是怎么回事:
1.报社的业务是出版报纸
2.向某家报社订阅报纸,只要他们有新报纸,就会给那你送来。只要你是他们的订户,你就会一直收到新报纸。
3.当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来了。
4.只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消订阅报纸。
出版者(主题)+订阅者(观察者)=观察者模式
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变了状态时,它的所有依赖者都会收到通知并自动更新。
当两个对象之间松耦合,它们仍然可以交互,但是不太清楚彼此的细节。
改变主题或观察者其中一方,并不影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由的改变它们。
设计原则:为交互对象之间的松耦合设计而努力。
#include <iostream>
#include <list>
#include <string>
using namespace std;
/*前向声明*/
class Observer;
/*主题接口*/
class Subject
{
public:
virtual void attach(Observer *o)=0;
virtual void change()=0;
virtual void setWeather(string str)=0;
virtual string getWeather()=0;
};
/*观察者接口*/
class Observer
{
public:
virtual string getName()=0;
virtual void update(Subject *s)=0;
};
/*主题实现*/
class Earth: public Subject
{
private:
string weather;
list<Observer* > *l;//指针
public:
Earth(){
l = new list<Observer*>;
}
void attach(Observer *o){
this->l->push_back(o);
}
void change(){
for(list<Observer*>::iterator it=l->begin();it!=l->end();++it)
{
(*it)->update(this);
}
}
void setWeather(string str)
{
this->weather=str;
change();
}
string getWeather()
{
return this->weather;
}
};
/*观察者实现*/
class Satellite:public Observer
{
private:
string name;
public:
Satellite(string str)
{
name=str;
}
string getName()
{
return name;
}
void update(Subject *s)
{
cout<<this->getName()+" "+s->getWeather();
}
};
int main()
{
Earth e;
Satellite *s1 = new Satellite("风云一号");
Satellite *s2 = new Satellite("风云二号");
Satellite *s3 = new Satellite("风云三号");
Satellite *s4 = new Satellite("风云四号");
e.attach(s1);
e.attach(s2);
e.attach(s3);
e.attach(s4);
e.setWeather("fine");
delete s1;
delete s2;
delete s3;
delete s4;
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
/*观察者接口*/
class Observer{
public:
virtual void update(float temp,float humidity,float pressure)=0;
virtual ~Observer(){
//cout<<"Observer"<<endl;
}
};
/*展示接口*/
class DisplayElement{
public:
virtual void display()=0;
virtual ~DisplayElement(){
//cout<<"displayElement"<<endl;
}
};
/*主题接口*/
class Subject
{
public:
virtual void registerObserver(Observer *o)=0;/*注册*/
virtual void notifyObserver()=0;/*通知*/
virtual ~Subject(){
//cout<<"Subject"<<endl;
}
};
/*主题实现*/
class WeatherData:public Subject{
public:
WeatherData():vec(new vector<Observer *>),temperature(0),humidity(0),pressure(0){}
void registerObserver(Observer *o)
{
vec->push_back(o);
}
void notifyObserver()
{
vector<Observer *>::iterator it=vec->begin();
while(it!=vec->end())
{
(*it)->update(temperature,humidity,pressure);
it++;
}
}
void measurementsChanged()
{
notifyObserver();
}
void setMeasurements(float t,float h,float p)
{
temperature=t;
humidity=h;
pressure=p;
measurementsChanged();
}
virtual ~WeatherData()
{
//cout<<"WeatherData"<<endl;
}
private:
vector<Observer *> *vec;
float temperature;
float humidity;
float pressure;
};
/*观察者实现之目前状况布告板*/
class CurrentConditionsDisplay:public Observer,public DisplayElement
{
public:
CurrentConditionsDisplay(Subject *w):weatherData(w),temperature(0.0),humidity(0.0)
{
weatherData->registerObserver(this);
}
void update(float t,float h,float p)
{
temperature=t;
humidity=h;
display();
}
void display()
{
cout<<"Current conditions:"<<temperature<<"F degress and "<<humidity<<"%d humidity"<<endl;
}
virtual ~CurrentConditionsDisplay()
{
//cout<<"CurrentConditionsDisplay"<<endl;
}
private:
float temperature;
float humidity;
Subject *weatherData;
};
int main()
{
WeatherData *w=new WeatherData();
CurrentConditionsDisplay *c=new CurrentConditionsDisplay(w);
w->setMeasurements(80,65,30.4f);
w->setMeasurements(82,70,29.2f);
w->setMeasurements(78,90,29.2f);
delete c;
delete w;
return 0;
}