【问题标题】:Is it bad practice to have a switch case in a switch case?在开关盒中放置开关盒是不好的做法吗?
【发布时间】:2013-08-22 12:56:35
【问题描述】:

在开关盒中放置开关盒是不好的做法吗?如果是这样,有什么替代方案?如果不需要,我真的不想使用if/else if

而不是做一些类似的事情:

if((this == 1) && (that == 1)){ //something }
else if((this == 1) && (that == 2)){ //something }
else if((this == 2) && (that == 3)){ //something }

我的想法是:

switch(this){
    case 1:
        switch(that){
            case 1:
                // something
            break;
            ....
        }
    break;
    ....
}

这对我来说真的很不对劲。语法上没有错,但在正确的做法上是错的。

【问题讨论】:

  • 我可以看到可以的情况。但我会盯着它看很久,看看能不能找到更简单的技术。
  • 实际上不是骗子,但有相关/有趣的信息:stackoverflow.com/questions/7807970/…
  • 要获得相关答案,最好将您的代码添加到问题中......
  • 而不是像这样: if((this == 1) && (that == 1)){ //something } else if((this == 1) && (that == 2 )){ //something } else if((this == 2) && (that == 3)){ //something } 我的思路是:switch(this){ case 1: switch(that){案例1:}休息; }

标签: javascript coding-style


【解决方案1】:

拥有大量功能来做很多不同的事情是不好的做法。如果您在 switch case 中有一个 switch case,则表明您的函数可能太大,您应该考虑将其拆分为更易于理解的小块。

但是没有一成不变的规则;这一切都取决于确切的场景。

【讨论】:

    【解决方案2】:

    避免以下方法

    switch(id)
    {
        case 1:
        {
            switch (subid)
            {
                case 4:
                    // nested code
            }
        }
        case 2:
             // some code
    }
    

    通过将嵌套部分移动到方法中来改进代码的首选方法

    switch(id)
    {
        case 1:
            SubSwtich(subid);
            break;
        case 2:
             // some code
    }
    
    function SubSwtich(int subid)
    {
            switch (subid)
            {
                case 4:
                    // nested code
            }
    }
    

    【讨论】:

    • 感谢大家的精彩回答。我感谢所有的见解。
    【解决方案3】:

    我认为这是一种不好的做法。在大多数情况下,这是不可读的。

    您可以将“子”开关案例提取到方法中。

    【讨论】:

      【解决方案4】:

      如果它使您的代码更难阅读,那么这是不好的做法。

      在您的特定示例中是否是这种情况由您决定,但总的来说我会说可能是这种情况。

      您要求替代方案...

      1. 将您的一些代码提取到子函数中。例如:

        case 'foo' :
            myVar = 'blah';
            break;
        case 'bar' :
            myVar = secondLevelFunction();
            break;
        

        这里,secondLevelFunction() 包含附加的 switch() 语句,其中每个 case 返回一个 myVar 的值。

      2. 使用数组映射。例如:

        var mapper = {'foo':'blah', 'bar':'bibble', etc};
        
        //now, instead of a big switch(input) { .... } block that sets myVar
        //for each option, you can just set it directly in a single line, like so:
        var myVar = mapper[input];
        

      此外,如果您正在寻找代码质量的具体衡量标准,您应该了解Cyclomatic Complexity。这是衡量函数复杂程度的指标。通过查看函数有多少“决策点”来进行测量。每个caseif、循环等都是一个“决策点”。你拥有的越多,你的功能就越复杂。

      圈复杂度与代码质量和良好的编码实践密切相关,因此,如果您的函数具有较高的 CC 分数(如果它有多个嵌套的 switch 块,它可能会这样做),那么它是糟糕代码的标志质量。我上面描述的两种替代解决方案都可以帮助解决这个问题。我会留给你阅读更多关于 CC 的内容。

      显然,替代解决方案需要适应您的需求,但希望它们能给您一些想法。

      【讨论】:

        【解决方案5】:

        您应该根据 switch 语句在不同的例程中中断代码,并且在例程中您也可以继续使用 switch case。就像跟随一样。

        private void Switch(int value)
            {
        
                switch (value)
                {
                    case 1:
                        SwitchNest(value);
                        break;
                    case 2:
                        break;
                }
            }
        
            private void SwitchNest(int value)
            { 
                switch (value)
                {
                    case 1:
                        SwitchOtherMethod(value);
                        break;
                    case 2:
                        break;
                }
            }
        

        【讨论】:

        • 我认为一次性使用的功能不值得。更不用说您现在在代码中跳转位置以遵循工作流程而不是一个位置。 (从可读性的角度来看,这可能是恕我直言,我宁愿筛选嵌套开关而不是追逐一次性功能。)
        【解决方案6】:

        不好的做法?不!可能在故障排除方面存在潜在的痛苦!看看你能做些什么来把所有的“选项”变成更有条理和更普遍联系的东西。甚至可以使用由发送的参数数量决定的方法重载来编写自己的函数。

        看看at this SO post,看看它是否能给你一些想法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-08
          • 1970-01-01
          • 2017-09-27
          相关资源
          最近更新 更多