Flyweight>();
?
?
?
?
?
?
?
?
private?
static?
readonly?
FlyweightFactory?
instance?
=?
new?
FlyweightFactory();
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
Constructors
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
private?
?
FlyweightFactory()
?
?
?
?
?
?
?
?
{?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
//?
Methods
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
从享元工厂中生产出一个具体的享元对象
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
name="key">内蕴状态
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
public?
Flyweight?
GetFlyweight(string?
key)
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
return?
((Flyweight)flyweights[key]);
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
享元工厂单例方法
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
public?
static?
?
FlyweightFactory?
Singleton()
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
return?
FlyweightFactory.instance;
?
?
?
?
?
?
?
?
}?
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
向享元工厂对象增加一个享元对象
?
?
?
?
?
?
?
?
///?
?
?
?
?
?
?
?
?
///?
name="sKey">内蕴状态
?
?
?
?
?
?
?
?
///?
name="_Flyweight">具体享元对象
?
?
?
?
?
?
?
?
public?
void?
AddFlyweight(string?
sKey,?
Flyweight?
_Flyweight)
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
flyweights.Add(sKey?
?
_Flyweight);
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
public?
Flyweight?
factory(string?
sKey)
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
if?
(flyweights.ContainsKey(sKey))
?
?
?
?
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
return?
this.GetFlyweight(sKey);
?
?
?
?
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
?
?
?
?
else
?
?
?
?
?
?
?
?
?
?
?
?
{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
this.AddFlyweight(sKey,?
new?
ConcreteFlyweight());
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
return?
this.GetFlyweight(sKey);
?
?
?
?
?
?
?
?
?
?
?
?
}?
?
?
?
?
?
?
?
?
?
?
?
?
}
?
?
?
?
}
///?
?
?
?
?
///?
测试代码
?
?
?
?
///?
?
class?
Test
{
publicstaticvoidmain()
{
?
?
?
?
//?
初始化外蕴状态值
?
?
?
?
?
?
?
?
?
?
?
?
int?
extrinsicstate?
=?
22;
?
?
?
?
?
?
?
?
?
?
?
?
//享元工厂对象使用单例
?
?
?
?
?
?
?
?
?
?
?
?
FlyweightFactory?
f?
=?
FlyweightFactory.Singleton?
()?
;
?
?
?
?
?
?
?
?
?
?
?
?
//调用过程
?
?
?
?
?
?
?
?
?
?
?
?
//向享元工厂对象请求一个内蕴状态为"X"的单纯享元对象
?
?
?
?
?
?
?
?
?
?
?
?
Flyweight?
fx?
=?
f.factory("X");
?
?
?
?
?
?
?
?
?
?
?
?
//调用X的商业方法,X的外蕴状态值为21
?
?
?
?
?
?
?
?
?
?
?
?
fx.Operation(--extrinsicstate);
?
?
?
?
?
?
?
?
?
?
?
?
Flyweight?
fy?
=?
f.factory("Y");
?
?
?
?
?
?
?
?
?
?
?
?
fy.Operation(--extrinsicstate);
?
?
?
?
?
?
?
?
?
?
?
?
Flyweight?
fz?
=?
f.factory("Z");
?
?
?
?
?
?
?
?
?
?
?
?
fz.Operation(--extrinsicstate);
}
}
publicinterfaceFlyweight{
publicvoidoperation(Stringstate);
}
publicclassConcerteFlyweightimplementsFlyweight{
//内蕴状态
privateCharacterintrinsicState=null;
//传进来的参数属于外晕状态
publicConcerteFlyweight(Characterstate){
this.intrinsicState=state;
}
publicvoidoperation(Stringstate){
}
}
publicclassFlyweightFactory{
privateHashMapflies=newHashMap();
privateFlyweightfly;
publicFlyweightFactory(){
}
//字体样式
publicFlyweightfactory(Characterstate){
if(flies.containsKey(state)){
return(Flyweight)flies.get(state);
}else{
fly=newConcerteFlyweight(state);
flies.put(state,fly);
returnfly;
}
}
}
publicclassClient{
publicstaticvoidmain(String[]args){
FlyweightFactoryfactory=newFlyweightFactory();
Flyweightfly=factory.factory(newCharacter('a'));
fly.operation("罗马字符");
fly.operation("新罗马字符");
fly=factory.factory(newCharacter('b'));
fly.operation("阿拉伯字符");
}
}
复合享元模式:
publicinterfaceFlyweight{
publicvoidoperation(Stringstate);
}
publicclassConcreteFlyweightimplementsFlyweight
{
privateCharacterintrinsicState=null;
//构造子,内蕴状态作为参数传入
publicConcreteFlyweight(Characterstate)
{
this.intrinsicState=state;
}
//外蕴状态作为参数传入方法
publicvoidoperation(Stringstate)
{
}
}
publicclassConcreteCompositeFlyweightimplementsFlyweight{
privateHashMapflies=newHashMap(10);
privateFlyweightflyweight;
publicConcreteCompositeFlyweight(){}
//增加一个新的单纯享元对象到聚集中
publicvoidadd(Characterkey,Flyweightfly)
{
flies.put(key,fly);
}
//外蕴状态作为参数传入到方法中
publicvoidoperation(StringextrinsicState)
{
Flyweightfly=null;
for(Iteratorit=flies.entrySet().iterator();it.hasNext();)
{
Map.Entrye=(Map.Entry)it.next();
fly=(Flyweight)e.getValue();
fly.operation(extrinsicState);
}
}
}
publicclassFlyweightFactory
{
privateHashMapflies=newHashMap();
publicFlyweightFactory(){}
//单纯享元工厂方法,所需状态以参量形式传入
publicFlyweightfactory(Characterstate)
{
if(flies.containsKey(state))
{
return(Flyweight)flies.get(state);
}else{
Flyweightfly=newConcreteFlyweight(state);
flies.put(state,fly);
returnfly;
}
}
//符合享元工厂方法,所需状态以参量形式传入,这个参量巧好可以使用string类型
publicFlyweightfactory(StringcompositeState)
{
ConcreteCompositeFlyweightcompositeFly=newConcreteCompositeFlyweight();
intlength=compositeState.length();
Characterstate=null;
for(inti=0;i{
state=newCharacter(compositeState.charAt(i));
compositeFly.add(state,this.factory(state));
}
returncompositeFly;
}
}
publicclassClient{
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
FlyweightFactoryfactory=newFlyweightFactory();
Flyweightfly=(Flyweight)factory.factory("abac");
fly.operation("罗马字符");
}
}
/*********************************
*设计模式--享元模式实现
*C++语言
*Author:
WangYong
********************************/
#include
#include
#include
#include
usingnamespacestd;
classFlyweight
{
public:
virtual~Flyweight(){}
virtualvoidOperation(conststring&extrinsicState){}
stringGetIntrinsicState(){returnthis->_intrinsicState;}
protected:
Flyweight(stringintrinsicState){this->_intrinsicState=_intrinsicState;}
private:
string_intrinsicState;
};
classConcreteFlyweight:
publicFlyweight
{
public:
ConcreteFlyweight(stringintrinsicState):
Flyweight(intrinsicState)
{cout<<"ConcreteFlyweightBuild...."<~ConcreteFlyweight(){}
voidOperation(conststring&extrinsicState)
{
cout<<"ConcreteFlyweight:
内蕴"<GetIntrinsicState()
<<"ConcreteFlyweight:
外蕴"<}
};
classFlyweightFactory
{
public:
FlyweightFactory(){}
~FlyweightFactory(){}
Flyweight*GetFlyweight(conststring&key)
{
vector:
:
iteratorit=_fly.begin();
for(;it!
=_fly.end();it++)
{
if((*it)->GetIntrinsicState()==key)
cout<<"alreadycreatedbyusers..."<return*it;
}
Flyweight*fn=newConcreteFlyweight(key);
_fly.push_back(fn);
returnfn;
}
private:
vector_fly;
};
intmain()
{
FlyweightFactory*fc=newFlyweightFactory();
Flyweight*fw1=fc->GetFlyweight("hello");
Flyweight*fw2=fc->GetFlyweight("world!
");
Flyweight*fw3=fc->GetFlyweight("hello");
}
典型应用:
一、享元模式在编辑器系统中大量使用。
一个文本编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。
享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字模风格等其他信息则是外蕴状态。
比如,字母a可能出现在文本的很多地方,虽然这些字母a的位置和字模风格不同,但是所有这些地方使用的都是同一个字母对象。
这样一来,字母对象就可以在整个系统中共享。
二、享元模式在.NETFramework中的应用。
String无论在.NET还是Java中,都是一个特殊的引用对象。
我们可以试想,出现了这样一段代码:
Strings=”Helloworld”;
Strings1=”Helloworld”;
那么是不是每次都要重新的去申请一块内存,然后去保存这个字符串呢?
那么这样的话是不是会效率很低呢?
因为我们知道,字符串在实际使用中往往都是非常短暂的。
他们通常是被读出来之后,便直接展示给了客户。
然后这个字符串的生命结束,变成垃圾。
在.NET和Java中,String都被以不变模式来进行设计。
我们来简单的分析一下String的驻留机制:
在CLR被加载之后,就会在SystemDomain的托管堆中去建立一个HashTable来维护String。
于是模拟代码如下:
(伪代码)
Hashtabletable;
if(!
tab