【问题标题】:Is there such a thing as too many embedded if-statements?是否有太多嵌入式 if 语句之类的东西?
【发布时间】:2011-06-30 14:09:09
【问题描述】:

目前我正在编写一些代码,(我相信)需要很多嵌入的 if 语句。是否有一些标准来嵌入多少 if 语句?我的大部分谷歌搜索都出现了与 excel 打交道的事情。不知道为什么。

如果有标准,为什么?是为了可读性还是为了让代码运行更顺畅?在我看来,它主要是为了可读性是有道理的。

我的 if 结构示例:

if (!all_fields_are_empty):
    if (id_search() && validId()):
        // do stuff
    else if (name_search):
        if (name_exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
    else if (name_search_type_2):
        if (exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
else:
    // you're stupid

我听说有 2-3 个嵌套的 for/while 循环的限制,但是 if 语句有一些标准吗?

更新: 我现在有几年的时间了。请不要使用这么多if 语句。如果你需要这么多,你的设计可能很糟糕。今天,我喜欢用最少的if 语句或switch 案例找到一种优雅的方式来完成这些事情。代码最终变得更简洁、更易于测试和更易于维护。正常。

【问题讨论】:

  • 我不是问最大是多少,我是问程序员的标准是什么。
  • 程序员之间没有“标准”最大值。每种情况都有它自己的嵌套最大值。例如,如果您有一些繁重的数学代码会进行一些可怕的计算 - 如果附近有注释解释它,我会很容易地使用 15 个嵌套 if 没有问题。但是,如果该代码的某些部分是可重用的 - 我会尝试以您可以重用它的方式拆分它们。
  • 对不起,我误解了这个问题。
  • 这是一个同行评议有益的地方。讨论应该如何“预先”编程,这样你就可以肯定七个嵌套的 if-s 是最好的方法,而不是其他方法。

标签: java coding-style if-statement


【解决方案1】:

正如 Randy 所提到的,这种代码的原因在大多数情况下是应用程序设计不佳。通常我会尝试在您的情况下使用“处理器”类。

例如,假设有一些名为“操作”的通用参数和30个不同参数的不同操作,你可以做一个接口:

interface OperationProcessor {
   boolean validate(Map<String, Object> parameters);
   boolean process(Map<String, Object> parameters);
}

然后为您需要的每个操作实现大量处理器,例如:

class PrinterProcessor implements OperationProcessor {
    boolean validate(Map<String, Object> parameters) {
       return (parameters.get("outputString") != null);
    }
    boolean process(Map<String, Object> parameters) {
       System.out.println(parameters.get("outputString"));
    }
}

下一步 - 当应用程序初始化时,您在某个数组中注册所有处理器:

public void init() {
    this.processors = new HashMap<String, OperationProcessor>();
    this.processors.put("print",new PrinterProcessor());
    this.processors.put("name_search", new NameSearchProcessor());
    ....
}

所以你的主要方法变成了这样:

String operation = parameters.get("operation"); //For example it could be 'name_search'
OperationProcessor processor = this.processors.get(operation);
if (processor != null && processor.validate()) { //Such operation is registered, and it validated all parameters as appropriate
   processor.process();
} else {
   System.out.println("You are dumb");
}

当然,这只是一个示例,您的项目可能需要一些不同的方法,但我想它可能与我所描述的相似。

【讨论】:

    【解决方案2】:

    我不认为有限制,但我不建议嵌入更多的两者 - 它太难阅读、难以调试且难以进行单元测试。考虑看看几本很棒的书,比如RefactoringDesign Patterns,也许还有Clean Code

    【讨论】:

    • 可能没有强制限制,每个人都建议尽可能保持 if 子句平坦 - 但我相信这可能是一个理论上的问题。数字是有限的还是无限的?我相信在Java程序(必须)崩溃之前它必须是有限数量的嵌套if子句。当然它不能是无限的数字......
    【解决方案3】:

    从技术上讲,我不知道嵌套有任何限制。

    如果您发现自己走得很深,这可能表明设计不佳。

    您发布的某些内容看起来最好用作case 声明。

    我会关心下一个人的可读性和代码维护,这实际上意味着很难——即使是第一个人(你)——一开始就做好。

    编辑:

    您也可以考虑创建一个类似于SearchableObject() 的类。你可以创建一个具有通用功能的基类,然后继承 ID、Name 等,这个顶级控制块将大大简化。

    【讨论】:

      【解决方案4】:

      从技术上讲,您可以拥有任意数量的数量,但如果数量过多,很快就会使代码变得不可读。

      我通常会做的事情是这样的:

      if(all_fields_are_empty) {
          abuseuser;
          return;
      }
      
      if(id_search() && validId()) {
        //do stuff
        return;
      }
      
      if(name_search)
      {
        if(name_exists)
          //do stuff
          return
        else
          //do stuff
          return
      }
      

      我确定你明白了

      【讨论】:

      • 当涉及到嵌套时,您确定这个数字可能是无限的吗?这更像是一个理论问题,但是如果我们创建一个不断增加嵌套的程序,直到 java 编译器无法再处理它怎么办?但诚然,这样一个问题的答案将有非常有限的用处......
      【解决方案5】:

      Tl;Dr尽管使用任何一种方法,您都不需要超过 10-15 条路径

      您在这里主要指的是Cyclomatic complexity

      圈复杂度是一种软件度量(度量),用于 表示程序的复杂性。它是一种量化的衡量标准 通过程序源的线性独立路径的数量 代码。它是由 Thomas J. McCabe, Sr. 于 1976 年开发的。

      因此,每个 if 语句都可能是您的代码的一条新路径,并增加了它的循环复杂性。有一些工具可以为您衡量这一点,并突出显示高度复杂的领域以进行潜在的重构。

      对于要嵌入多少个 if 语句是否有一些标准?

      是和不是。人们普遍认为(McCabe 本人也认为)超过 10 或 15 的圈复杂度太高了,这表明代码应该被重构。

      McCabe 最初的应用之一是限制 程序开发过程中的例程;他建议程序员 应该计算他们正在开发的模块的复杂性,并且 每当 模块超过 10.[2]这种做法被 NIST 采用 结构化测试方法,观察到由于 McCabe 的原始出版物,10 的数字已收到 大量确凿的证据,但在某些情况下 可能是适当的放宽限制和允许模块 复杂性高达 15。正如该方法所承认的那样 是超出商定限制的偶然原因,它 将其建议表述为:“对于每个模块,无论是限制 圈复杂度达到 [商定的限制] 或提供书面的 解释超出限制的原因。”[7]

      但这并不是一个真正的硬性规则,在某些情况下可以忽略。看到这个问题What is the highest Cyclomatic Complexity of any function you maintain? And how would you go about refactoring it?

      为什么?是为了可读性还是为了让代码运行得更多 顺利吗?

      本质上这是为了可读性,这应该使您的代码运行顺畅。引用Martin Fowler

      任何傻瓜都可以编写计算机可以理解的代码。好的 程序员编写人类可以理解的代码。

      【讨论】:

        【解决方案6】:

        Java 中嵌套 if/else 块数量的唯一技术限制可能是堆栈的大小。风格是另一回事。

        顺便说一句:冒号是怎么回事?

        【讨论】:

        • 我刚刚快速输入了一些内容,作为我的 if 结构的示例。我猜是我的 Python 体验的一部分。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        相关资源
        最近更新 更多