组织多个长开关

时间:2018-11-07 03:41:18

标签: c++ switch-statement

这可能取决于意见,但我不知道,这就是我要问的原因。

在一种方法中,我将有几个长的switch语句。 (我有多个从0x3F-> 0x00切换Uint8的实例,并假设我不必交换案例中使用的变量)这将使该方法变得很长且难以导航。有什么有效的方法可以使代码更具导航性?我最初的想法是为每个方法创建多个单独的方法,但我不知道这如何影响周期或构建时间。

这是一个截断的代码示例,将出现几种变体,但具有不同的大小写效果,需要分开:

    switch (surroundingTiles) {
                                //Using Sprite 30
                            case 0x09:
                                renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[30], viewPort, 120, NULL, SDL_FLIP_NONE);
                                break;
                            case 0x12:
                                renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[30], viewPort, 0, NULL, SDL_FLIP_NONE);
                                break;
                            case 0x24:
                                renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[30], viewPort, 60, NULL, SDL_FLIP_NONE);
                                break;
***
***
***
                    //using sprite 41
                    case 0x3F:
                        renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[41], viewPort, 0, NULL, SDL_FLIP_NONE);
                        break;

                    //throw error sprite
                    default:
                        renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[6], viewPort, 0, NULL, SDL_FLIP_NONE);
                        break;

以下是我正在考虑的快速伪内容:

switchMethod1();
//some code
switchMethod2();

其中每个方法都包含一个冗长的switch语句。

2 个答案:

答案 0 :(得分:1)

根据您显示的代码:
//Using Sprite 30块和//Using Sprite 41块之间的变化是m_sprite数组的索引。
//Using Sprite 30块中,更改随viewport后的参数发生。让我们称之为seaPort

因此,查找表似乎是一个不错的选择:

static const Uint8 SeaPortLookUp[256] = {120, 0, 60, .... 60, 0, 120};
static const Uint8 SpriteLookUp[256] = {30, 41, 6, .... 6, 30, 41};

然后switch语句可以重写为:

spriteIndex = SpriteLookUp[surroundingTiles]; 
seaPort = SeaPortLookUp[surroundingTiles]; 
renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[spriteIndex], viewPort, seaPort, NULL, SDL_FLIP_NONE);

答案 1 :(得分:0)

我有两种风格建议:

首先,请尽一切可能将重复相同字符的次数降到最低。

例如,在您发布的代码中,您的所有(或大多数)案件看起来像这样:

renderer->render(xPos, yPos, renderable->getRenderable(), &m_sprite[30], viewPort, 120, NULL, SDL_FLIP_NONE);

...进行一些变量重命名,和/或在切换语句的顶部声明一些局部变量,您可以将其简化为:

r->render(x, y, r2, &ms[30], vp, 120, NULL, SDL_FLIP_NONE);

使内容保持尽可能简短的原因很简单:键入的文字越少,读取和调试的文字越少,因此验证和维护表也越容易。

(通过使用内联帮助函数和/或宏,您可能会走得更远,但是收益递减的地方是简洁变成晦涩)

我的第二个建议是,如果您的代码充当大表/电子表格,则可以将其格式化为大表/电子表格。

例如,代替此:

switch (surroundingTiles) {
  case 0x09:
     r->render(x, y, r2, &ms[30], vp, 120, NULL, SDL_FLIP_NONE);
  break;
  case 0x12:
     r->render(x, y, r2, &ms[25], vp, 32, NULL, SDL_FLIP_NONE);
  break;
  case 0x24:
     r->render(x, y, r2, &ms[2], vp, 1, NULL, SDL_FLIP_NONE);
  break;
  [...]

....如果可以的话,使其看起来更像这样

switch (surroundingTiles) {
   case 0x09: r->render(x, y, r2, &ms[30], vp, 120, NULL, SDL_FLIP_NONE); break;
   case 0x12: r->render(x, y, r2, &ms[25], vp,  32, NULL, SDL_FLIP_NONE); break;
   case 0x24: r->render(x, y, r2, &ms[2],  vp,   1, NULL, SDL_FLIP_NONE); break;
   [...]

之所以这样做,是因为如果您可以将各列彼此排列起来,那么眼睛就可以轻松上下扫描各列以查找错误和错别字-一切“与众不同”如果您不必分别左右扫描以定位每一行的起始位置,则对给定列的查找会容易得多。 (当然,可能会过度使用它,并最终导致一行很长的行,除非在非常宽的显示器上,否则它们是无法查看的)

switchMethod1();
//some code
switchMethod2();

将一个大功能分解为几个较小的功能绝不是一个坏主意,尤其是如果每个较小的功能具有单独且易于描述的目的。 (即,如果很容易为函数想出一个直观的/自我描述的名称,那么您就走在正确的轨道上)切换/案例语句不能总是很容易地以这种方式分开(例如,有时您可能想要只执行switchMethod1()而不是switchMethod2(),而不是总是执行它们两者)