处理很多if-else,切换

cpp*_*ool 2 c++ if-statement switch-statement

处理这样的事情的最佳方法是什么:

if(key==Space)
{
    switch(weapon)
    {
        case GUN:
            p->shotGun();
            break; 
        case BOW:
            p->shotBow();
            break;
    }
}
else if(key==Enter)
{
    //...
}
else if(key==Up)
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

小智 10

将一维拆分为两个:

switch (key)
{
  case Space:
    ProcessSpaceCmd ();
    break;

  case Enter:
    ProcessEnterCmd ();
    break;

  case Up:
    ProcessUpCmd ();
    break;
}
Run Code Online (Sandbox Code Playgroud)

查看哪个尺寸更长,[key]或者[weapon]使用最短的外部开关.

  • 如果开发人员不小心,这可能导致意大利面条仓库,但考虑到OP的需求,这是明智的. (2认同)

tva*_*son 9

您可能想要考虑使用Command和/或Strategy模式.Command模式似乎非常适合外部if/else,而Strategy模式似乎非常适合内部开关.

  cmd = Command->GetCommand( key );
  cmd->Perform();
Run Code Online (Sandbox Code Playgroud)

并在执行与空格键关联的命令

  weapon = PlayState->GetCurrentWeapon();
  weapon->Fire();
Run Code Online (Sandbox Code Playgroud)

请注意,后者依赖于一些全局缓存/状态来保存当前武器(策略).

这样做的结果是将if/else逻辑移动到您确定当前命令的工厂方法中.选择哪个命令选择其中一个if/else分支.将当前武器存储在游戏状态允许您轻松选择要调用的武器的Fire方法,因此选择武器的开关"逻辑"将移动到状态的武器选择逻辑并完全"消失".每种武器策略都知道如何执行它自己的"火"逻辑.


whe*_*ies 5

我倾向于使用地图类型表达式:

unordered_map<KEY_PRESS,ICommand> myCommands;
unordered_map<KEY_PRESS,ICommand>::const_iterator currentCommand = myCommands.find( key );
if( currendCommand != myCommands.end() ){
    currentCommand->performAction( weapon );
}
Run Code Online (Sandbox Code Playgroud)

再说一次,如果你把武器变成对象而不是标志,你就可以摆脱重载的函数模式.