游戏编程技巧 - Subclass Sandbox

Subclass Sandbox

使用场景

你正在开发一款类似LOL的游戏,里面有许多英雄角色,你决定把这些英雄类交给小弟们实现。因为在这些英雄中,释放放技能时,有的要使用粒子系统造成炫酷的效果,有的要播放音效来震慑对手,有的要使用物理引擎来进行仿真,因此这些英雄类需要与系统的其他部分交互。之后,你在开发时,发现音频系统中部分全局参数被改掉了,物理引擎里也一样,终于你发现是小弟们的英雄类改了这些系统的参数/状态。为了系统能安全地运行,你决定使用sandbox技术来限制小弟们能进行的操作。

描述

父类定义abstract的sandbox方法,并提供部分操作方法,(以上方法均是protected),子类利用父类提供的操作方法去实现sandbox方法。


代码例子(C#)

//英雄基类
public abstract class BaseHero
{
    protected abstract void ReleaseSkill();

    protected void PlaySound(int soundId) {}
    protected void PlayPhysics(int physicsId) {}
    protected void PlayEffect(int effectId) {}
}
//英雄-剑圣
public class Blademaster : BaseHero
{
    private const int SOUND_ID = 1;
    private const int EFFECT_ID = 3;
    protected override void ReleaseSkill()
    {
        PlaySound(SOUND_ID);
        PlayEffect(EFFECT_ID);
        //other code
    }
}

在这里,英雄类剑圣在实现释放技能的方法时,只需要调用父类中的PlaySound和PlayEffect方法,而自己不需要去操作其他模块。


优点

  • 子类不需要经常与其他系统模块交互,保证了系统的稳定
  • 子类的实现变得简单,因为大多数需要的操作都可以在父类中找到

缺点

  • 导致fragile base class问题,因为子类太依赖父类了
  • 父类需要与其他模块交互
  • 父类变得庞大而复杂

fragile base class 问题
当父类进行修改时,你不能确定子类会不会出故障

设计决策

1.父类应该提供什么操作

  • 如果某操作只有小部分子类受益,则该操作父类可以不提供
  • 如果某操作影响广泛,交给子类直接操作是不安全的,则父类封装并提供该操作

2.什么时候把操作交给具体类来处理

如果父类已经很庞大,可以将某些操作交给具体的类来管理,父类只需要返回该类

  • 比如音频管理器、UI管理器等
  • 降低了父类和其他系统模块的耦合度:当系统其他部分变化了的时候,只有该管理类需要变化,父类不需要进行改变

参考

游戏设计模式


上一篇:js当中的声明和初始化的顺序


下一篇:虚拟机下CentOS找不到网卡eth0的解决方法