九
16
定义
享元(Flyweight)模式是指,运用共享技术有效地支持大量细粒度的对象。
结构

理解
1. Flyweight是享元抽象基类。Flyweight::Operation是公共接口,享元依赖的外部状态(ExtrinsicState)通过接口参数传入。
2. ConcreteFlyweight是具体享元类。具体享元必须是可共享的,必须为内部状态(IntrinsicState)提供存储空间。
3. UnshareConcreteFlyweight是不可共享的具体享元,也叫做复合享元。复合享元是由单纯具体享元通过复合(Composite)模式而成的,将若干个具体享元作为子节点。
4. FlyweightFactory是享元工厂。创建并管理享元对象。当Client请求一个享元对象时,FlyweightFactory返回一个已创建的享元对象(如果没有就先创建)。
5. Client维护一个指向Flyweight的指针,并且存储Flyweight的外部状态。
要点
1. 一个应用程序使用了大量相同的对象。对于相同的对象只需要共享一份就可以了。如文本文档中字符对象就会大量存在,如果不使用享元模式,就要使用大量的对象,将会耗费大量的存储开销。
2. 对于文本文档的字符对象,字符代码是内部状态,字体字号大小排版位置等是外部状态。对象的大多数状态都可变为外部状态。
3. 外部状态可以由一个单独的外部对象来存储。如文本文档,外部对象存储文档的排版信息。
应用
用文本文档来说明享元模式的应用。
源码中没有演示不可共享的具体享元。可通过引入行对象(Row),将Character作为Row的子节点来实现,Row就是不可共享的享元。
源码
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
//外部状态. 存放字体大小和位置
class CContext
{
public:
CContext() : m_iIdx(0) {};
void AppendFontSize(const int iFontSize)
{
m_vecFontSize.push_back(iFontSize);
}
int GetCharSize()
{
return m_vecFontSize[m_iIdx];
}
int GetCharIdx()
{
return m_iIdx;
}
void Next()
{
m_iIdx++;
}
private:
int m_iIdx;
vector<int> m_vecFontSize;
};
//Flyweight
class CFlyweight
{
public:
CFlyweight(){};
virtual ~CFlyweight(){};
//享元方法,context是外部状态,通过参数传入
virtual void ShowInfo(CContext &context) = 0;
};
//ConcreteFlyweight
class CCharacter : public CFlyweight
{
public:
CCharacter(const char c) : m_c(c) {};
virtual void ShowInfo(CContext &context)
{
cout << "IntrinsicState: char=" << m_c << "; ExtrinsicState: index=" << context.GetCharIdx() << ", size=" << context.GetCharSize() << endl;
context.Next();
};
protected:
char m_c; //内部状态
};
//FlyweightFactory. 可用单件模式. 不考虑释放资源
class CFlyweightFactory
{
public:
CFlyweight* GetFlyweight(const char c)
{
map<char, CFlyweight*>::iterator itr = m_mapPool.find(c);
if (itr != m_mapPool.end())
{
cout << c << " already exists." << endl;
return itr->second;
}
cout << c << " added." << endl;
CFlyweight* p = new CCharacter(c);
m_mapPool[c] = p;
return p;
};
private:
map<char, CFlyweight*> m_mapPool;
};
int main()
{
CFlyweightFactory factory;
CContext context;
CFlyweight* p = NULL;
p = factory.GetFlyweight(‘a’);
context.AppendFontSize(8);
p->ShowInfo(context);
p = factory.GetFlyweight(‘b’);
context.AppendFontSize(9);
p->ShowInfo(context);
p = factory.GetFlyweight(‘c’);
context.AppendFontSize(10);
p->ShowInfo(context);
p = factory.GetFlyweight(‘b’);
context.AppendFontSize(11);
p->ShowInfo(context);
return 0;
}
输出:
a added.
IntrinsicState: char=a; ExtrinsicState: index=0, size=8
b added.
IntrinsicState: char=b; ExtrinsicState: index=1, size=9
c added.
IntrinsicState: char=c; ExtrinsicState: index=2, size=10
b already exists.
IntrinsicState: char=b; ExtrinsicState: index=3, size=11
转载本站文章请注明,转载自:神秘果
本文链接: http://www.shenmiguo.com/archives/2009/311_design-patterns-flyweight.html

Leave a Reply