如何编写 if 条件语句,以及何时一种方法比另一种更好

How to program if conditionals, and when does one approach become better than the other

我想知道,主要是作为一种行业标准方法,或者作为一种明确的最佳实践方法,人们通常如何对 if 条件进行编程。

我发现自己经常使用下面的第一种方法,从来没有真正遇到过问题。但我仍然想知道什么时候应该使用。

这只是一个例子来说明我的意思,不应将其视为通常使用的比较的正常复杂度。

例子

public class Validation {
   int x = 5,
       y = 10,
       z = 100,
       a = 1;

    public void compare() {
        if (x < y) {
            // Do Something
            if (y < z) {
                // Do Something
                if (z < a) {
                    System.out.println("Whatever");
                }
            }
        }
    }

    public void alternate() {
        if (compareNumbers(x, y)) {
            // Do something
            if (compareNumbers(y, z)) {
                // Do something
                if (compareNumbers(z, a)) {
                    System.out.println("Whatever");
                }

            }
        }
    }

    public boolean compareNumbers(int a, int b) {
        return a < b;
    }
}

其中哪一个是更好的练习?这是一个超级简单的示例,假设您通常会使用更复杂的验证。

如果 'alternate' 更好,那么需要调用多少次比较 method/function 才能更好?

很抱歉,如果它属于 StackExchange,我不太确定 post 它属于哪一个。

为了缩小 Whosebug 的范围,假设这个问题只适用于 Java。虽然一般编程 view/response 将不胜感激。

根据我的个人经验,如果我知道条件始终保持不变,我会使用原始比较,但是如果有哪怕是最微小的机会需要更改条件,我也会使用替代方法。这样我就不必返回并单独替换每个条件。

将代码提取到方法有几个优点:

  1. 它使代码可读
  2. 它允许轻松更改方法的实现
  3. 它允许对该特定方法进行单元测试

如果您的方法所做的只是将 < 运算符应用于两个参数,我会说上述三个原因中的 none 都适用,并且您使事情过于复杂. 只需使用 < 方法,并在需要应用更多 "meat" 的测试时重构您的代码。

没有"industry standards"这种东西。有充分的理由。

至于a < b是否比compareNumbers(a, b)更好……答案取决于实际情况。

在您的示例中,大多数人会同意 a < b 更好 1。但这是一个人为的例子,其他(更现实的)例子的答案可能会有所不同。

关于在代码中表达算法等的最佳方式的各种其他问题也是如此。像这样的问题很少有一个客观正确的答案。这通常是一个见仁见智的问题……上下文真的很重要。


但归根结底,这里唯一真正的 "industry standard" 是:

Use your professional knowledge, skills and judgement.

...这意味着:

  • 思考每个特定问题并找到合适的(合理的)解决方案,
  • 考虑编码工作、可读性2、可靠性、解决方案的可维护性,
  • 考虑经济情况;也就是说,在花费 "polishing" 编写代码的时间与花费在执行其他事情(例如实现功能、测试、编写文档、按时完成任务)上的时间之间存在权衡。

1 - 如果我必须向下滚动几页来检查 compareNumbers 在做什么,这是一个障碍......与使用 [=14= 的内联比较相比].现在,如果比较背后有更深层次的语义,那么方法抽象可能是一件好事,特别是如果方法中有解释语义的注释。但是在这个例子中,compareNumbers(a, b) a < b.

在语义上 的意义更小

2 - 另一个答案指出(没有支持证据)将代码抽象为方法可以提高可读性。这是一种严重的过度简化,而且通常明显是错误的。这是一项重要的技术......但并不总是正确的。

实际上,我关注的是代码的复杂性 以及该逻辑在我的项目 中的重要性。因此,我可能会在同一个 class 甚至同一个方法中使用所有备选方案。

要建立在分解方法的基础上,我知道你的例子只是一个简单的例子,但我不会专注于评估,而是专注于任务并像这样组织代码:

     public void someMethodThatCares(int x, int y, int z, int a)
     {
         taskXY(x, y);
     }

     public void taskXY(int x, int y)
     {
         if (x < y)
         {

             taskYZ(y, z);
         }

     }

     public void taskYZ(int y, int z)
     {
         if (y < z)
         {

             taskZA(z, a);
         }
     }

     public void taskZA(int z, int a)
     {
         if (z < a)
         {

         }
     }

现在您可以根据需要构建依赖项,独立测试每个功能,以干净的方式维护逻辑,并根据需要重用它。

我建议阅读“四人帮”的 Design Patterns 以了解有关如何做出决定的更多信息。对于每个问题,方法都会有所不同。例如,如果您需要编写多个程序来单独检查每个变量,第一个程序执行小于检查,第二个程序执行大于检查,第三个程序执行等于检查,那么对每个程序使用策略设计模式可能是有意义的这些情况避免需要创建多个程序并使用工厂创建者来决定使用哪个策略。工厂模式可以根据用户输入或其他一些方法在 运行 时决定使用哪一个。