代理模式(Flyweight)属于结构模式,享元模式提供了一种比较好的通过共享较少程序开销的方法。具体的做法是对于一个对象,在使用它的时候把不会变化的参数就把它作为内部状态,而会变化的就作为外部状态。对象的生成用一个工厂类来完成,工厂类负责维护一张关于对象的表,在外部申请对象时如果查到表里有,就直接返回表里已有的对象,如果没有,那么就生成一个新的放到表里,这种方式就避免了每要求一个对象就重新生成一个。在外部调用对象功能的时候,只需要传递外部的状态即可。
下面是享元模式的C++实现,代码可到本人github网页下载:设计模式例子
/*
* Example of 'Flyweight' design pattern.
* Copyright (C) 2016 Leo Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <map>
using namespace std;
class CFlyweight
{
public:
virtual void Do(string exstate)=0;
};
class CConcreteFlyweight:public CFlyweight
{
private:
string m_instate;
string m_id;
public:
CConcreteFlyweight(string id)
{
m_instate="Instate is invariable in general.";
m_id=id;
};
public:
void Do(string exstate)
{
cout<<m_instate<<endl;
cout<<"Exstate is "<<exstate<<endl;
};
};
class CFlyweightFactory
{
public:
map<string,CFlyweight*> flyweights;
public:
CFlyweight* GetFlyweight(string id)
{
CFlyweight* p_flyweight;
auto it=flyweights.find(id);
if(it==flyweights.end())
{
p_flyweight=new CConcreteFlyweight(id);
flyweights[id]=p_flyweight;
}
else
{
p_flyweight=it->second;
};
return p_flyweight;
};
};
int main()
{
CFlyweightFactory* cp_factory=new CFlyweightFactory();
CFlyweight* cp_flyweight1=cp_factory->GetFlyweight("A");
CFlyweight* cp_flyweight2=cp_factory->GetFlyweight("B");
CFlyweight* cp_flyweight3=cp_factory->GetFlyweight("A");
cp_flyweight1->Do("Hello world!");
cp_flyweight1->Do("Hello China!");
cp_flyweight1->Do("Hello America!");
return 1;
};
在这个例子中,实际上只生成了两个对象,但是使用的时候却是当三个用的。