行为模式之观察者模式(Observer Pattern)(C++实现)******

观察者模式(Observer Pattern)行为模式.

它是应用最多,影响最广的模式之一,因为Observer的一个实例Model/View/Control(MVC)结构在系统开发构架中有着很重要的地位和意义,MVC实现了业务逻辑和表示层的解耦。Observer模式是软件开发过程中必须要掌握的和使用的模式之一。Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。Observer模式就是解决了这一个问题。

设计原则:为了交互对象之间的松耦合设计而努力。

出版者+订阅者=观察者模式

定义:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态,它的所有依赖者都会收到通知并自动更新。


主题对象(管理某些数据)------(一旦主题内的数据改变就会通知观察者)--------à观察者对象(狗对象,猫对象)

实现观察者模式的方法不止一种,但是以包含Subject和Observer接口的类设计的做法最常见。

气象站观察者模式类设计图:



注意这里的ObserverUpdate操作并不在Observer改变了Subject目标状态的时候就对自己进行更新,这个更新操作要延迟到Subject对象发出Notify通知所有Observer进行修改(调用Update)。

C++实现:

Subject.h头文件

#ifndef _SUBJECT_H_
#define _SUBJECT_H_
#include 
#include 
using namespace std;

class Observer;
class Subject  //主题接口
{


public:
virtual ~Subject();
virtual void Register(Observer* obv);
virtual void Remove(Observer* obv);
virtual void Notify();//当主题改变时,用这个方法通知所有的观察者

protected:

Subject();
private:


};
class WeatherData:public Subject
{
public:
 WeatherData();
~WeatherData();
 void Register(Observer* obv);//注册对象
 void Remove(Observer* obv);
 void Notify();//当主题改变时,用这个方法通知所有的观察者
 void measurementsChanged();
 void setMeasurements(float temperature,float humidity,float pressure);

protected:
private:

list* _obvs;  //保存注册的观察者
float temperature;
float humidity;
float pressure;
};

#endif

Subject.CPP源文件

#include "Subject.h"
#include "Observer.h"
#include 
#include 
using namespace std;


Subject::Subject()
{
	
}
Subject::~Subject()
{

}
void Subject::Register(Observer *obv)
{
 
}
void Subject::Remove(Observer *obv)
{
	
}
void Subject::Notify()
{
	
}


WeatherData::WeatherData()
{
 _obvs=new list;
}
WeatherData::~WeatherData()
{
 
}

void WeatherData::Register(Observer *obv)
{
 if(obv!=NULL)
	 _obvs->push_front(obv);
}
void WeatherData::Remove(Observer *obv)
{
	if(obv!=NULL)
		
   _obvs->remove(obv);
}
void WeatherData::Notify()
{
	list::iterator it;
	it=_obvs->begin();
	for(;it!=_obvs->end();it++)
	{
		(*it)->Update(this->temperature,this->humidity,this->pressure);
	}
}
void WeatherData::measurementsChanged()
{
	Notify(); //数值更新,通知观察者

}
void WeatherData::setMeasurements(float temperature, float humidity, float pressure)
{
	this->temperature=temperature;
	this->humidity=humidity;
	this->pressure=pressure;
	measurementsChanged();
}

Observer.h头文件

//Observer.h
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include "Subject.h"
#include 
using namespace std;
typedef string State;
class Observer
{
public:
	virtual ~Observer();
	virtual void Update(float temperature,float humidity,float pressure)=0;
    
 
};
class DisplayElement
{
public:
virtual ~DisplayElement();
virtual void display()=0;

};
/*当前状态公告板,实现Observer接口,所以可以从WeatherData对象中获取改变*/
/*规定所有的公告板必须实现DisplayElement接口*/
class CurrentConditionDisplay:public Observer,public DisplayElement
{ 
	
public:
  CurrentConditionDisplay(Subject *sub);
  ~CurrentConditionDisplay();
   void Update(float temperature,float humidity,float pressure);
   void display();
private:
Subject *sub;
float temperature;
float humidity;


};

#endif

Observer.CPP源文件

#include "Subject.h"
#include "Observer.h"
#include 
#include 
using namespace std;
//typedef string state;
Observer:: ~Observer()
{

}
DisplayElement::~DisplayElement()
{

}
CurrentConditionDisplay::CurrentConditionDisplay(Subject *sub)
{
	this->sub=sub;
	sub->Register(this);
}

CurrentConditionDisplay::~CurrentConditionDisplay()
{
	sub->Remove(this);
	if(sub!=0)
		delete sub;
}
void CurrentConditionDisplay::Update(float temperature,float humidity,float pressure)
{
	this->temperature=temperature;
	this->humidity=humidity;
    display();
}
void CurrentConditionDisplay::display()
{
	cout<<"Current condition: "<temperature<<"F degrees and "<humidity<<"% humidity"<

主函数main.CPP

#include "Subject.h"
#include "Observer.h"
#include 
using namespace std;
int main(int argc,char* argv[])
{

   WeatherData *weatherData=new WeatherData(); //建立气象站
   CurrentConditionDisplay *currentDisplay=new CurrentConditionDisplay(weatherData);//建立一个公告板,并注册一个观察者Observer,加入其中
   weatherData->setMeasurements(80,65,65.4f);//气象站数据变化
   weatherData->setMeasurements(81,78,65.4f); //setMeasurements调用Notify()通知所有的公告板更新数据并显示调用Update()函数,而公告板重载Observer的Update()
   //从而达到所有的公告板随着weatherData对象即气象站的数据而更新显示
   if (NULL != weatherData)
   delete weatherData;
 
	return 0;
}








复制 搜索

你可能感兴趣的:(C/C++,STL,泛型编程,设计模式与软件构架,编程规范)