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

[GoF设计模式]Flyweight模式和State模式的C++实现

2009-10-05 11:05 776 查看
【Flyweight模式】

一个应用程序创建了太多的对象,会造成很大的存储开销,特别是大量轻量级的对象。对于这种情况,可以将对象的状态分成外部状态和内部状态,将可以被共享(不变化)的状态作为内部状态存储在对象中,而外部状态则可以将外部对象作为参数传递给对象。Flyweight有一个类似工厂模式的对象构造工厂,当程序需要一个对象时就会向FlyweightFactory发出请求对象的消息,该工厂拥有一个管理、存储对象的仓库(或者称为对象池),FlyweightFactory中会遍历对象池,如果存在则直接返回,否则创建并返回。同时程序也可以向FlyweightFactory请求不被共享的对象。

【图解】

以纯文本为例,每个字符CharFlyweight为共享的轻量级对象,而由这些字符构成的行则为非共享的对象RowFlyweight,而TextFlyweightFactory则管理其共享对象的对象池。当用户向该工厂请求字符时,就从对象池中取得,而当用户向该工厂请求字符串时候则通过创建非共享的RowFlyweight获取,但此种每个字符的获取仍然向TextFlyweightFactory共享对象的对象池提出请求。



【程序】

]/*******************************************************************
*
*    DESCRIPTION:Text Flyweight Factory Class
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef TEXTFLYWEIGHTFACTORY_H_
#define TEXTFLYWEIGHTFACTORY_H_
/** include files **/
#include <vector>
#include "CharFlyweight.h"
using namespace std;
/**
* TextFlyweightFactory: provide the CharFlyweight object
*
* @author roy nee (2009-10-4)
*/
class TextFlyweightFactory
{
public:
/*Constructor and destructor*/
TextFlyweightFactory(){}
virtual ~TextFlyweightFactory(){}
/// <summary>
/// Get the CharFlyweight Object
/// </summary>
/// <param name="_char"></param>
/// <returns></returns>
virtual AbstractFlyweight* GetFlyweight(char _char)
{
vector<CharFlyweight*>::iterator iter=this->_vecCharFlyweight.begin();
for(;iter!=this->_vecCharFlyweight.end();++iter)
{
if((*iter)->GetChar()==_char)return *iter;
}
CharFlyweight *newchar=new CharFlyweight(_char);/*new character*/
this->_vecCharFlyweight.push_back(newchar); /*Record it*/
return newchar;
}
virtual AbstractFlyweight* GetFlyweight(string str)
{
RowFlyweight *row=new RowFlyweight();
for(int i=0;i<str.length();++i)
row->AddFlyweight(this->GetFlyweight(str[i]));  /*Get the char from VecCharFlyweight*/
return row;
}
/// <summary>
/// Just be used to show the size of vector
/// </summary>
/// <returns></returns>
virtual int SizeVector()
{
return this->_vecCharFlyweight.size();
}
private:
/*CharFlyweight Vector*/
vector<CharFlyweight*> _vecCharFlyweight;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: AbstractFlyweight Class [Abstract Class Of Flyweight]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef ABSTRACTFLYWEIGHT_H_
#define ABSTRACTFLYWEIGHT_H_
/** include files **/
#include <iostream>
using namespace std;
/**
* AbstractFlyweight Class[Abstract Class]
*
* @author roy nee (2009-10-4)
*/
class AbstractFlyweight
{
public:
AbstractFlyweight(){}
virtual ~AbstractFlyweight(){}
/// <summary>
/// Interface of Writing the Element of Flyweight
/// </summary>
/// <returns></returns>
virtual void Write()=0;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: Char Flyweight Class [Concrete Flyweight Class]
*                 SharedFlyweight Class
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef CHARFLYWEIGHT_H_
#define CHARFLYWEIGHT_H_
/** include files **/
#include "AbstractFlyweight.h"
class CharFlyweight:public AbstractFlyweight
{
public:
/*constructor and destructor*/
CharFlyweight(char tChar)
{
this->_Char=tChar;
}
virtual ~CharFlyweight(){}

/// <summary>
/// Interface of Writing the Element of Flyweight
/// </summary>
/// <returns></returns>
virtual void Write()
{
cout<<this->_Char<<flush;
return;
}
/// <summary>
/// Get the Char
/// </summary>
/// <returns></returns>
virtual char GetChar()
{
return this->_Char;
}
private:
char _Char;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION:Row Flyweight Class [Unshared Flyweight Class]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef ROWFLYWEIGHT_H_
#define ROWFLYWEIGHT_H_
/** include files **/
#include <vector>
#include "AbstractFlyweight.h"
using namespace std;
class RowFlyweight:public AbstractFlyweight
{
public:
RowFlyweight(){}
virtual ~RowFlyweight(){}
/// <summary>
/// Interface of Writing the Element of Flyweight
/// </summary>
/// <returns></returns>
virtual void Write()
{
for(vector<AbstractFlyweight*>::iterator iter=this->_vecFlyweight.begin();iter!=this->_vecFlyweight.end();++iter)
(*iter)->Write();
return;
}
virtual void AddFlyweight(AbstractFlyweight * flyweight)
{
this->_vecFlyweight.push_back(flyweight);
}
private:
vector<AbstractFlyweight*> _vecFlyweight;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION:Flyweight Pattern [享元模式]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
/** include files **/
#include <iostream>
#include "CharFlyweight.h"
#include "RowFlyweight.h"
#include "TextFlyweightFactory.h"
using namespace std;
int main (int argc, char *argv[])
{
/*Now There is A factory*/
TextFlyweightFactory *factory=new TextFlyweightFactory();
/*Now Get CharFlyweight-shared*/
factory->GetFlyweight('a')->Write();
factory->GetFlyweight('a')->Write();
factory->GetFlyweight('c')->Write();
cout<<"/nFactory's Size is: "<<factory->SizeVector()<<endl;
/*Now New a Row-unshared*/
factory->GetFlyweight("hello")->Write();
return(0);
}


【输出】



【State模式】

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。FSM有限状态自动机也是一个典型的状态模式,对输入有同的相应(状态转移),通常情况会写很多switch case 或者 if else语句,当状态数目很多时,维护一组swith case 很困难,状态逻辑和动作没能实现分开,在系统实现中,动作的实现代码直接写在状态逻辑中,使得系统的扩展性和维护性得不到保证。state模式也有问题是,状态逻辑分散到了很多state子类中,很难看到整个逻辑状态图,代码的维护难度也会加大。一般而言状态采用单例模式。注意单例模式中cpp文件中现代码,单例的初始化 GreenState* GreenState::_instance=0;必须在cpp文件中,在h文件中直接初始化或者不写编译会出问题。

【图解】

以交通灯的红灯和绿灯状态为例子(简单起见省略黄灯状态),交通灯(Context),红灯/绿灯状态(Concrete State,状态采用单例模式)



【程序】

]/*******************************************************************
*
*    DESCRIPTION:Traffic Light Class [Context Class]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef TRAFFICLIGHT_H_
#define TRAFFICLIGHT_H_
/** include files **/
#include "TrafficLightState.h"
class TrafficLightState;/*predeclaration*/
/**
* Traffic Light Class
*
* @author roy nee (2009-10-4)
*/
class TrafficLight
{
public:
TrafficLight(TrafficLightState *state);
virtual ~TrafficLight();
/// <summary>
/// Change the State of Traffic Light
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
virtual void ChangeState(TrafficLightState *state);
/// <summary>
/// Just See the State of TrafficLight
/// </summary>
/// <returns></returns>
virtual void ShowState();
private:
TrafficLightState *_state;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION:
*
*    AUTHOR:
*
*    DATE:2009-10-4
*
*******************************************************************/
/** include files **/
#include "TrafficLight.h"
TrafficLight::TrafficLight(TrafficLightState *state)
{
this->_state=state;
}
TrafficLight::~TrafficLight(){}
void TrafficLight::ChangeState(TrafficLightState *state)
{
this->_state=state;/*set the state*/
return;
}
void TrafficLight::ShowState()
{
this->_state->ShowState();
return;
}


]/*******************************************************************
*
*    DESCRIPTION:Traffic Light State [Abstract State Class]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef TRAFFICLIGHTSTATE_H_
#define TRAFFICLIGHTSTATE_H_
/** include files **/
#include <iostream>
#include "TrafficLight.h"
using namespace std;
class TrafficLight;/*Predeclaration*/
/**
* TrafficLight State
*
* @author roy nee (2009-10-4)
*/
class TrafficLightState
{
public:
virtual ~TrafficLightState();
virtual void SetTrafficLight(TrafficLight *trafficlight)=0;
virtual void ShowState()=0;
protected:/*Singleton Pattern: constructor should be protected or private*/
TrafficLightState();
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: TrafficLightState CPP File
*
*    AUTHOR:
*
*    DATE:2009-10-4
*
*******************************************************************/
/** include files **/
#include "TrafficLightState.h"
TrafficLightState::TrafficLightState()
{
}
TrafficLightState::~TrafficLightState()
{
}


RedState和GreenState类似,省略.....

]/*******************************************************************
*
*    DESCRIPTION:Green State Class [Concrete State Class]
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
#ifndef GREENSTATE_H_
#define GREENSTATE_H_
/** include files **/
#include "TrafficLightState.h"
/**
* Green State Class : Concrete State
*
* @author roy nee (2009-10-4)
*/
class GreenState:public TrafficLightState
{
public:
/*Singleton Pattern's interface to get object instance*/
static GreenState* Instance()
{
if(_instance==0)_instance=new GreenState();
return _instance;
}

virtual ~GreenState();
virtual void SetTrafficLight(TrafficLight *trafficlight);
virtual void ShowState();
protected:
GreenState();/*Singleton Pattern: private or pretected*/
private:
static GreenState* _instance;
};
#endif


]/*******************************************************************
*
*    DESCRIPTION: GreenState cpp
*
*    AUTHOR:Neesky
*
*    DATE:2009-10-4
*
*******************************************************************/
/** include files **/
#include "GreenState.h"
/*Very Important for Singleton Pattern, it must be written in cpp file*/
GreenState* GreenState::_instance=0;
GreenState::GreenState()
{

}
GreenState::~GreenState()
{
}
void GreenState::SetTrafficLight(TrafficLight *trafficlight)
{
trafficlight->ChangeState(this);
}
void GreenState::ShowState()
{
cout<<"Traffic Light: Green......"<<endl;
return;
}


【输出】

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