享元模式,Flyweight,在面向对象设计中,创建对象是极为正常的事情了,然而,当我们到处创建对象还是在创建同一种类型的对象或者同一种抽象类型的对象时,显得好低效,浪费内存。比如,当一篇文章,每个字符都是一个对象,字母a肯定出现了很多遍,如果每次都要建立一个对象,工作量就很大了,试想,如果我们共享同一个对象“a”,只是在不同的地方显示不同的字体、颜色等,设计时将对象a分为内部和外部两种状态,对于共享的部分设为内置,不共享的部分设为外置,那么事情会变得很省劲儿。这个方法就是享元的思想。
UML图:
从上图能看到有一个工厂FlyweightFactory在里面,当client需要一个对象,比方说a,就可以想FlyweightFactory发送一个请求GetFlyweight(),Flyweight拥有一个管理、存储对象的仓库,或者成为对象池,可以用vector或hash表实现,GetFlyweight会遍历对象池中的对象,如果已经存在a就直接返回给client,否则,创建一个对象返回给client,最右边部分是不想被共享的对象,本模式暂不讲解。Flyweight是享元类接口,内置部分的信息包含在这个类里面,concreteFlyweight是具体实现部分,外置部分在其中。
代码:
#ifndef _FLYWEIGHT_H__
#define _FLYWEIGHT_H__
#include <vector>
#include <string>
using namespace std;
class flyweight
{
public:
virtual ~flyweight();
virtual void operation(const string&);
string get_intrinsic_state();
protected:
flyweight(string);
private:
string _in_str;
};
class concrete_flyweight:public flyweight
{
public:
concrete_flyweight(string);
~concrete_flyweight();
void operation(const string&);
};
class flyweight_factory
{
public:
flyweight_factory();
~flyweight_factory();
flyweight *get_flyweight(const string&);
private:
vector<flyweight*> _fly;
};
#endif
//flyweight.cpp
#include "flyweight.h"
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
using namespace std;
flyweight::flyweight(string intrinsic_state)
{
_in_str = intrinsic_state;
}
flyweight::~flyweight()
{
}
void flyweight::operation(const string &extrinsic_state)
{
}
string flyweight::get_intrinsic_state()
{
return _in_str;
}
concrete_flyweight::concrete_flyweight(string intrinsic_state)
:flyweight(intrinsic_state)
{
cout<<"concrete flyweight created"<<endl;
}
concrete_flyweight::~concrete_flyweight()
{
}
void concrete_flyweight::operation(const string &extrinsic_state)
{
cout<<"concrete flyweight intrinsic_state :"<<get_intrinsic_state();
cout<<"extrinsic_state :"<<extrinsic_state<<endl;
}
flyweight_factory::flyweight_factory()
{
}
flyweight_factory::~flyweight_factory()
{
//destructor work defualted
}
flyweight *flyweight_factory::get_flyweight(const string &key)
{
vector<flyweight*>::iterator ite = _fly.begin();
for ( ; ite != _fly.end(); ++ite)
{
if (key == (*ite)->get_intrinsic_state() )
{
cout<<"already created..."<<endl;
return *ite;
}
}
flyweight *temp = new concrete_flyweight(key);
_fly.push_back(temp);
return temp;
}
//main.cpp
#include "flyweight.h"
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
flyweight_factory * p_fac = new flyweight_factory();
flyweight *p_fly1 = p_fac->get_flyweight("jack");
flyweight *p_fly2 = p_fac->get_flyweight("rose");
flyweight *p_fly3 = p_fac->get_flyweight("jack");
return 0;
}
g++ -o flyweight main.cpp flyweight.cpp
千万要分清gcc还是g++,不然,除bug你会很头疼。