《游戏编程模式》学习笔记(十二)子类沙箱 Subclass Sandbox

定义

基类定义抽象的沙箱方法和几个提供的操作。 将操作标为protected,表明它们只为子类所使用。 每个推导出的沙箱子类用提供的操作实现了沙箱函数。

举个例子

假设我们在做一个超级英雄的游戏,我们现在要实现一些超能力。我们计划创建一个Superpower基类。然后由它派生出各种超级能力的实现类。 由于超能力种类繁多,而且逻辑各异,有些超能力要进行大量的物理计算,有些超能力需要大量掉哟个到游戏的动画系统,有些超能力需要播放很多音频…

这意味着这些超能力需要与游戏引擎内的方法产生大量的交互调用。而且如果有些引擎的API发生了改变,可能会有大量的超能力类要重写。这样可不好,耦合性太高了,我们讨厌如此多的大量耦合。
这个时候我们就可以使用子类沙箱的方法来避免这一情况。我们要做的就是统一将所有的方法都放在基类的protected字段下,而子类都通过访问基类中的这些方法来实现自己的功能。这样就可以将众多的子类和引擎代码解耦。

代码如下:

class Superpower
{
public:
  virtual ~Superpower() {}

protected:
  virtual void activate() = 0;

  void move(double x, double y, double z)
  {
    // 实现代码……
  }

  void playSound(SoundId sound, double volume)
  {
    // 实现代码……
  }

  void spawnParticles(ParticleType type, int count)
  {
    // 实现代码……
  }
};
然后实现某一个子类
class SkyLaunch : public Superpower
{
protected:
  virtual void activate()
  {
    // 空中滑行
    playSound(SOUND_SPROING, 1.0f);
    spawnParticles(PARTICLE_DUST, 10);
    move(0, 0, 20);
  }
};

我们通过将耦合约束到一个地方解决了耦合问题。 Superpower最终与不同的系统耦合,但是继承它的几百个类不会。 相反,它们只耦合基类。 当游戏系统的某部分改变时,修改Superpower也许是必须的,但是众多的子类不需要修改。这就是子类沙箱模式。

何时使用子类沙箱?

• 你有一个能推导很多子类的基类。
• 基类可以提供子类需要的所有操作。
• 在子类中有行为重复,你想要更容易地在它们间分享代码。
• 你想要最小化子类和程序的其他部分的耦合。

你可能感兴趣的:(游戏实用技术专栏,读书笔记,游戏,学习,笔记)