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

享元模式成员分析
没看懂,也许后面会更新罢。
享元模式代码结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| abstract class Flyweight { public abstract void Operation(int extrinsicstate); }
class ConcreteFlyweight : Flyweight { public override void Operation(int extrinsicstate) { Console.Write("具体的Flyweight" + extrinsicstate); } }
class UnsharedConcreteFlyweight : Flyweight { public override void Operation(int extrinsicstate) { Console.WriteLine("不共享的具体Flyweight" + extrinsicstate); } }
class FlyweightFactory { private Hashtable flyweights = new Hashtable(); public FlyweightFactory() { flyweights.Add("x", new ConcreteFlyweight()); flyweights.Add("y", new ConcreteFlyweight()); flyweights.Add("z", new ConcreteFlyweight()); } public Flyweight GetFlyweight(string key) { return (Flyweight)flyweights[key]; } }
|
享元模式总结
问题:
一定要在工厂里面事先实例化对象实例嘛?
不一定,可以在工厂实例化时什么都不做,到需要使用时,再判断GetFlyweight(key)是否为null,是则实例化一个对象实例。
Unshared的享元存在的意义何在?
有一些时候的特例,有可能存在不需要共享的实例对象。
关键
内部状态和外部状态
享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本相同,有时就能够大幅度地减少需要实例化的类的数量。如果能够把那些参数移到类实例的外面,在方法调用时再将它们传递进来,就可以通过共享去大幅度地减少单个实例的数目。
内部状态存储在具体享元当中
将外部状态作为方法参数存放于具体享元的方法中
考虑将外部状态放在客户端中存储或计算。
享元模式应用场景
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时,应该考虑使用享元模式。
此外,如果对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
游戏开发中的享元模式
享元模式用于在多个对象之间共享相同的数据。
例如,游戏场景中的一些植被和重复得小物件,它们的贴图或是网格都是一样的,可以创建一个公共的对象来记录这些数据,我称之为共享数据,然后他们的位置,朝向可能都不一样,这些数据我称之为私有数据。
如我们要在游戏场景中绘制1k棵树,在未使用享元模式之前:
1 2 3 4 5 6 7 8 9 10 11 12
| class Tree { private: Mesh mesh_; Texture bark_; Texture leaves_; Vector position_; double height_; double thickness_; Color barkTint_; Color leafTint_; };
|
使用享元模式之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class TreeModel { private: Mesh mesh_; Texture bark_; Texture leaves_; }; class Tree { private: TreeModel* model_; Vector position_; double height_; double thickness_; Color barkTint_; Color leafTint_; };
|
这样我们就只需要创建一个Model对象,让所有的树都引用这份数据,而不是每棵树都拥有自己的网格数据,可以节约内存。以上例子来源于《游戏设计模式》。
使用享元模式的前提是,他们的数据必须是可以共享的,即有相同的数据。