享元模式 - Flyweight

Flyweight(享元模式)

定义

GOF:运用共享技术有效地支持大量细粒度的对象。
GOF的定义比较专业化,通俗来说,当你有大量相似的实例时,你把其中相同的实例取出来共享。

例子

在你的游戏场景中,你需要用到多种地形,比如草地(Grass)、山脉(Hill)、河流(River)等,如下所示:
享元模式 - Flyweight
地形的类设计如下:

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");
...

进一步

上面提到的例子是一个简化的版本,*提出的版本要复杂一点,但是思想都是一样的。我们可以根据需要进行相应的修改。
享元模式 - Flyweight


参考

  1. Game Programming Patterns
  2. 大话设计模式

上一篇:C# 计算文件MD5


下一篇:css制作倒三角