设计模式:享元模式(Flyweight)
定 义:运用共享技术有效地支持大量细粒度的对象。
结构图:
内部状态:在享元对象内部并且不会随环境而改变的共享部分。
外部状态:随环境改变而改变的、不可共享的状态。
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 = 22; 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。
注意:如果再有一个字符串s3,它的初始值为“测试字符串”,再对它进行操作s3 = s3 + “一”,这时虽然s1和s3的值相同,但是它们的引用是不同的。