观察者模式

我们先看看报社和杂志的订阅是怎么回事:

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值