Flyweight(享元模式)
定义
GOF:运用共享技术有效地支持大量细粒度的对象。
GOF的定义比较专业化,通俗来说,当你有大量相似的实例时,你把其中相同的实例取出来共享。
例子
在你的游戏场景中,你需要用到多种地形,比如草地(Grass)、山脉(Hill)、河流(River)等,如下所示:
地形的类设计如下:
public class Terrain {
private Texture tex;
private int moveCost; //玩家移动速度损耗
public Terrain(Texture t, int mc) {
tex = t;
mc = moveCost;
}
}
很明显,同样类型地形的上述两个数据都是一样,如果像下面这样:
map[0,3] = new Terrain(GrassTex, 1);
map[1,0] = new Terrain(GrassTex, 1);
每个方格都创建一个新的实例,很明显是十分浪费内存的。更好的做法应该是:
Terrain grass = new Terrain(GrassTex, 1);
map[0,3] = grass;
map[1,0] = grass;
这样,我们就把一些相同的实例抽取了出来进行共享,降低了内存消耗。为了更好地管理这些地形实例,我们可以用一个单例的工厂类来进行管理:
public class TerrainFactory {
private TerrainFactory _Instance;
private TerrainFactory() {}
public Instance() {
//一些单例代码
}
private Hash<string, Terrain*> TerrainHash;
public Terrain* GetTerrain(string type) {
if(!TerrainHash.ContainKey(type))
return null;
return TerrainHash[type];
}
public void Add(string type, Terrain* terrain) {
if(!TerrainHash.ContainKey(type))
TerrainHash.Add(type, terrain);
}
}
这样我们就能这样使用了:
TerrainFactory factory = TerrainFactory.Instance();
factory.Add("Grass", new Terrain(GrassTex, 1));
factory.Add("River", new Terrain(RiverTex, 10));
factory.Add("Hill", new Terrain(HillTex, 5));
map[0,0] = factory.GetTerrain("Hill");
map[0,1] = factory.GetTerrain("River");
...
进一步
上面提到的例子是一个简化的版本,*提出的版本要复杂一点,但是思想都是一样的。我们可以根据需要进行相应的修改。
参考
- Game Programming Patterns
- 大话设计模式