Flyweight(享元)设计模式

时间:2021-12-08 19:52:54

声明:本博文篇幅短,适合review。

一、概念

        运用共享技术,有效地支持大量细粒度的对象。减少内存消耗。它有两个状态:

       内部状态:存储在享元对象内部,并且不会随环境改变而改变的对象,可以共享。

       外部状态:随环境改变而改变的对象,不可共享。

二、结构模式图

       Flyweight(享元)设计模式

class Flyweight
{
public:
virtual ~Flyweight();
virtual void Operation(const std::string & _others){}

std::string getState(){
return this->m_state;
}
protected:
Flyweight(std::string _state){
this->m_state = _state;
}
private:
std::string m_state;
};

class ConcreteFlyweight : public Flyweight
{
public:
ConcreteFlyweight(std::string _state) : Flyweight(_state) {}
~ConcreteFlyweight();

void Operation(const std::string & _others)
{
cout<<"ConcreteFlyweight Operation : "<<m_state<<endl;
};
};

class FlyweightFactory
{
public:
FlyweightFactory();
~FlyweightFactory();

Flyweight * getFlyweight(const std::string & key){
std::vector<Flyweight *>::iterator it = m_Vec.begin();

for (; it != m_Vec.end() ; it++){
if ( (*it)->getState() == key )
{
cout<<"has created"<<endl;
return *it;
}
}

Flyweight * fw = new ConcreteFlyweight(key);
m_Vec.push_back(fw);
return fw;
}
private:
std::vector<Flyweight *> m_Vec;
};

void main(){
FlyweightFactory * fc = new FlyweightFactory();
Flyweight * fw1 = fc->getFlyweight("xxx");
Flyweight * fw2 = fc->getFlyweight("yyy");
Flyweight * fw3 = fc->getFlyweight("xxx");
}

三、例子

class Chess
{
public:
virtual ~Chess();
virtual void draw(const std::string & _color){}

std::string getState(){
return this->m_state;
}
protected:
Chess(std::string _state){
this->m_state = _state;
}
private:
std::string m_state;
};

class FiveChess : public Chess
{
public:
FiveChess(std::string _state) : Chess(_state) {}
~FiveChess();

void draw(const std::string & _color)
{
cout<<"FiveChess draw : "<<m_state<<" "<<_color<<endl;
};
};

class ChessFactory
{
public:
ChessFactory();
~ChessFactory();

Chess * getChess(const std::string & key){
std::vector<Chess *>::iterator it = m_Vec.begin();

for (; it != m_Vec.end() ; it++){
if ( (*it)->getState() == key )
{
cout<<"has created"<<endl;
return *it;
}
}

Chess * c = new FiveChess(key);
m_Vec.push_back(c);
return c;
}
private:
std::vector<Chess *> m_Vec;
};

void main(){
ChessFactory * cf = new ChessFactory();
Chess * c1 = cf->getChess("white");
c1.draw("白色");
Chess * c2 = cf->getChess("black");
c2.draw("黑色");
Chess * c3 = cf->getChess("white");
c3.draw("白色");
}


四、优缺点

       1、优点

            a、极大的减少系统中对象的个数。

            b、享元模式使得享元对象能够在不同的环境被共享。

       2、缺点

            a、使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

       b、享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。