定 义:运用共享技术有效地支持大量细粒度的对象。
结构图:
内部状态:在享元对象内部并且不会随环境而改变的共享部分。
外部状态:随环境改变而改变的、不可共享的状态。
Flyweight类,具体享元类的超类和接口,通过这个接口,Flyweight可以接受并作用于外部状态。
abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
ConcreteFlyweight继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。
class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("具体Flyweight:" + extrinsicstate);
}
}
UnshareFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。
class UnShareConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
}
}
FlyweightFactory,是一个共享工厂,用来创建并管理Flyweight对象。它主要确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在)。
class FlyweightFactory
{
private Hashtable flyweihts = new Hashtable(); public Flyweight GetFlyweight(string key)
{
if (!flyweihts.ContainsKey(key))
{
flyweihts.Add(key, new ConcreteFlyweight());
} return (Flyweight)flyweihts[key];
}
}
客户端调用:
int extrinsicstate = ;
FlyweightFactory f = new FlyweightFactory(); Flyweight fx = f.GetFlyweight("X");
fx.Operation(--extrinsicstate); Flyweight fy = f.GetFlyweight("Y");
fx.Operation(--extrinsicstate); Flyweight fz = f.GetFlyweight("Z");
fx.Operation(--extrinsicstate); UnShareConcreteFlyweight uf = new UnShareConcreteFlyweight();
uf.Operation(--extrinsicstate);
结果:
享元模式的优点:
大幅度地降低内存中对象的数量。
享元模式的缺点:
1:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
2:享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
总结:
享元模式一般是解决系统性能问题的,所以经常用于底层开发,在项目开发中并不常用。
.NET的享元模式:
.NET中的String类型就是运用了享元模式。.NET中如果第一次创建了一个字符串对象s1,下次再创建相同的字符串s2时只是把它的引用指向s1所引用的具体对象,这就实现了相同字符串在内存中的共享。下面的程序来演示s1和s2的引
用是否一致: 输出的结果为True。
string s1 ="测试字符串一";
string s2 ="测试字符串一";
Console.WriteLine(Object.ReferenceEquals(s1, s2));
注意:如果再有一个字符串s3,它的初始值为“测试字符串”,再对它进行操作s3 = s3 + “一”,这时虽然s1和s3的值相同,但是它们的引用是不同的。