您的位置:首页 > 编程语言 > C语言/C++

[GoF设计模式]Decorator模式和Observer模式的C++实现

2009-09-22 16:47 645 查看
【Decorator模式】

Decorator模式提供了一种给类增加职责的方法,不是通过直接继承实现的,而是通过组合,下图中的WorkerDecorator类可以派生很多在Worker基础上扩展出来的类,而不仅仅只是SeniorWorker,可以有不同的扩展。这是装饰者模式的威力所在。

但是如果只是给WorkComponent添加一个修饰,WorkDecorator可以省去,但以后可扩展性就不强了。

注意:基类指针指向派生类时,通过该指针只能访问到基类中所提供的接口。

Decorator采用组合的方式取得了比采用继承的方式更好的效果。

【图解】

普通的工人能够进行粉墙和喷漆的工作,现在需要技术工人,即掌握粉墙和喷漆的能力外,还需要有进行设计的能力。



【程序】

]/*******************************************************************
*
*    DESCRIPTION: WorkerComponent[工人] Class (Component Class in Decorator Pattern)
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-22
*
*******************************************************************/
#ifndef WORKERCOMPONENT_H_
#define WORKERCOMPONENT_H_
class WorkerComponent
{
public:
WorkerComponent(){}
virtual ~WorkerComponent(){}
/*activities of worker*/
virtual void painting()=0;//Worker must can paiting[会喷漆]
virtual void brushing()=0;//Worker must can brushing[会刷墙]
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Worker Class [Concreate Component Class in Decorator Pattern]
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-22
*
*******************************************************************/
#ifndef WORKER_H_
#define WORKER_H_
/** include files **/
#include <iostream>
#include "WorkerComponent.h"
using namespace std;
class Worker:public WorkerComponent
{
public:
Worker(){}
virtual ~Worker(){}
/*activities of worker*/
virtual void brushing()
{
cout<<"Hi,I am a Worker, and I am brushing......"<<endl;
return;
}
virtual void painting()
{
cout<<"Hi,I am a Worker, and I am painting......"<<endl;
return;
}
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: WorkerDecorator Class, inherited from WorkComponent
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-22
*
*******************************************************************/
#ifndef WORKDECORATOR_H_
#define WORKDECORATOR_H_
/** include files **/
#include "WorkerComponent.h"
class WorkerDecorator:public WorkerComponent
{
public:
/*constructor and destructor*/
WorkerDecorator(WorkerComponent *workerComponent)
{
this->_workcomponent=workerComponent;
}
virtual ~WorkerDecorator()
{
if(this->_workcomponent!=NULL)
delete this->_workcomponent;
}
/*Inherited from WorkerComponent*/
//virtual void painting()=0;
//virtual void brushing()=0;
protected:/*Very Important:protected*/
WorkerComponent *_workcomponent;//Key Point to use the Worker's capability
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: SeniorWorker[资深工人] ,inherited from WorkerDecorator Class
*
*    AUTHOR:Neesky [Concreate Decorator Class ]
*
*    DATE:2009-9-22
*
*******************************************************************/
#ifndef SENIORWORKER_H_
#define SENIORWORKER_H_
/** include files **/
#include "WorkerDecorator.h"
class SeniorWorker:public WorkerDecorator
{
public:
/*constuctor and destructor*/
SeniorWorker(WorkerComponent *workerComponent):WorkerDecorator(workerComponent)
{
}
virtual ~SeniorWorker()
{
if(this->_workcomponent!=NULL)delete this->_workcomponent;
}
/*activities of worker*/
virtual void brushing()
{
cout<<"Senior Worker:"<<flush;
this->_workcomponent->brushing();
return;
}
virtual void painting()
{
cout<<"Senior Worker:"<<flush;
this->_workcomponent->painting();
return;
}
/*Additional Function: activities of senior worker*/
virtual void designing()
{
cout<<"Senior Worker:Hi,I am a senior worker,and I am designing......"<<endl;
return;
}
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Main Program [Decorator模式]-装饰者模式
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-22
*
*******************************************************************/
/** include files **/
#include <iostream>
#include "Worker.h"
#include "WorkerComponent.h"
#include "SeniorWorker.h"
using namespace std;
int main (int argc, char *argv[])
{
/*Prototype Pattern*/
WorkerComponent* worker=new Worker();
cout<<"/nNow Here is a worker......"<<endl;
worker->brushing();//Brush wall first
worker->painting();//Paint later
/*SeniorWorker  must have capability of worker object*/
SeniorWorker *seniorworker=new SeniorWorker(worker);
cout<<"/nNow Here is a senior worker......"<<endl;
seniorworker->designing();
seniorworker->brushing();
seniorworker->painting();
return(0);
}


【输出】



【Observer模式】

Observer模式是应用最多影响最广的模式,MVC就是基于Observer模式的,改模式在系统开发和设计过程中有重要意义,MVC实现了业务层和表示层的解耦。Observer模式也是开发过程中必须要掌握的使用模式之一。

建个一(subject)对多(observer)的关系,当一发生变化的时候,依赖一的多也能同步改变。

【图解】

当温度数据发生变化时,我们期望反应温度数据的柱状图型和曲线图也能同步做出更新。



【程序】

]/*******************************************************************
*
*    DESCRIPTION: Data Subject Class
*
*    AUTHOR: Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
#ifndef DATASUBJECT_H_
#define DATASUBJECT_H_
/**include files**/
#include <list>
using namespace std;
#include "DataObserver.h"
/*Predeclaration*/
class DataObserver;
class DataSubject
{
public:
/*constructor and destructor*/
DataSubject()
{
this->obList=new list<DataObserver*>;
this->Data=0.0;
}
virtual ~DataSubject()
{
if(this->obList!=NULL)
delete this->obList;
}
/*Interface Functions*/
virtual void AttachObserver(DataObserver *observer)
{
this->obList->push_back(observer);
return;
}
virtual void DetachObserver(DataObserver *observer)
{
list<DataObserver*>::iterator it=std::find(this->obList->begin(), this->obList->end(), observer);
if(it!=this->obList->end())
this->obList->erase(it);
return;
}
/*Notify Observers As obList*/
virtual void NotifyObservers_toUpdate()
{
list<DataObserver*>::iterator iter=obList->begin();
for(;iter!=obList->end();++iter)
(*iter)->Update();
return;
}
/*Get Or Set Data*/
virtual void SetData(double _newData)=0;
virtual double GetData()=0;

protected:
double Data;
list<DataObserver*> *obList;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Temperature Data Class 温度数据类
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
#ifndef TEMPERATUREDATA_H_
#define TEMPERATUREDATA_H_
/** include files **/
#include "DataSubject.h"
class TemperatureData:public DataSubject
{
public:
/*constructor and destructor*/
TemperatureData(){}
virtual ~TemperatureData(){}

/*implement the interface*/
virtual double GetData()
{
return this->Data;
}
virtual void SetData(double _newData)
{
if(this->Data!=_newData)
{
this->Data=_newData;
this->NotifyObservers_toUpdate();/*Notify Observers*/
}
return;
}
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Data Observer Class
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
#ifndef DATAOBSERVER_H_
#define DATAOBSERVER_H_
/**include files**/
#include "DataSubject.h"
/*Predeclaration*/
class DataSubject;
class DataObserver
{
public:
DataObserver(){}
virtual ~DataObserver(){}
/*Interface Functions*/
virtual void Update()=0;
protected:
DataSubject *_datasubject;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION:Graph Observer Class[数据的曲线图表示]
*
*    AUTHOR: Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
#ifndef GRAPHOBSERVER_H_
#define GRAPHOBSERVER_H_
/** include files **/
#include "DataObserver.h"
class GraphObserver:public DataObserver
{
public:
/*constructor and destructor*/
GraphObserver(DataSubject* datasubject)
{
this->_datasubject=datasubject;
this->_datasubject->AttachObserver(this);/*Register: observe*/
}
virtual ~GraphObserver()
{
if(this->_datasubject!=NULL)
this->_datasubject->DetachObserver(this);/*Un Register*/
}
/*Implement Interface*/
virtual void Update()
{
this->dataView=this->_datasubject->GetData();/*Updata local data copy*/
return;
}
/*get method*/
virtual double GetDataView()
{
return this->dataView;
}
private:
double dataView;/*local data copy*/
};
#endif


/*******************************************************************
*
*    DESCRIPTION:Histogram Observer Class[数据的曲线图表示]
*
*    AUTHOR: Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
#ifndef HISTOGRAMOBSERVER_H_
#define HISTOGRAMOBSERVER_H_
/** include files **/
#include "DataObserver.h"
class HistogramObserver:public DataObserver
{
public:
/*constructor and destructor*/
HistogramObserver(DataSubject *datasubject)
{
this->_datasubject=datasubject;
this->_datasubject->AttachObserver(this);/*Register: observe*/
this->Update();
}
virtual ~HistogramObserver()
{
if(this->_datasubject!=NULL)
this->_datasubject->DetachObserver(this);/*Un Register*/
}
/*Implement Interface*/
virtual void Update()
{
this->dataView=this->_datasubject->GetData();/*Updata local data copy*/
return;
}

/*get method*/
virtual double GetDataView()
{
return this->dataView;
}

private:
double dataView;/*local data copy*/
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Observer Patterns [观察者模式]
*
*    AUTHOR:Neesky
*
*    DATE:2009-9-23
*
*******************************************************************/
/** include files **/
#include <iostream>
using namespace std;
#include "TemperatureData.h"
#include "GraphObserver.h"
#include "HistogramObserver.h"
int main (int argc, char *argv[])
{
/*Now there is a temperature data*/
DataSubject *temperature=new TemperatureData();
/*Now there are serveral observers*/
GraphObserver *graphForTemperature=new GraphObserver(temperature);
HistogramObserver *histogramForTemperature=new HistogramObserver(temperature);
/*Now temperature changed to be 37.5 C*/
cout<<"/nNow Temperature is changed to be 37.5 C!"<<endl;
temperature->SetData(37.5);/*Call the NotifyObservers_toUpdate, it call Observers' update method*/
/*See Graph's view data if changed*/
cout<<"GraphObserver's temperature dataView is: "<<graphForTemperature->GetDataView()<<endl;
cout<<"HistogramObserver's temperature dataView is: "<<histogramForTemperature->GetDataView()<<endl;
cout<<"/nNow Detach the GraphObserver......";
temperature->DetachObserver(graphForTemperature);
cout<<"Ok"<<endl;
/*Now temperature changed to be 37.5 C*/
cout<<"/nNow Temperature is changed to be 40.3 C!"<<endl;
temperature->SetData(40.3);/*Call the NotifyObservers_toUpdate, it call Observers' update method*/
/*See Graph's view data if changed*/
cout<<"GraphObserver's temperature dataView is: "<<graphForTemperature->GetDataView()<<endl;
cout<<"HistogramObserver's temperature dataView is: "<<histogramForTemperature->GetDataView()<<endl;
return(0);
}


【输出】

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: