代码之家  ›  专栏  ›  技术社区  ›  Christopher Klewes

将布尔检查提取到局部变量

  •  1
  • Christopher Klewes  · 技术社区  · 15 年前

    有时我会将布尔检查提取到局部变量中,以获得更好的可读性。

    你怎么认为?

    有什么缺点吗?

    如果变量没有在其他任何地方使用,编译器是一行输入还是其他什么?我还考虑用一个附加的“”块来缩小范围。

    if (person.getAge() > MINIMUM_AGE && person.getTall() > MAXIMUM_SIZE && person.getWeight < MAXIMUM_WEIGHT) {
        // do something
    }
    

    final boolean isOldEnough = person.getAge() > MINIMUM_AGE;
    final boolean isTallEnough = person.getTall() > MAXIMUM_SIZE;
    final boolean isNotToHeavy = person.getWeight < MAXIMUM_WEIGHT;
    
    if (isOldEnough && isTallEnough && isNotToHeavy) {
        // do something
    }
    
    9 回复  |  直到 15 年前
        1
  •  11
  •   skaffman    15 年前

    我一直这样做。这样代码的可读性要高得多。不这样做的唯一原因是它禁止运行时进行快捷优化,尽管智能虚拟机可能会发现这一点。

        2
  •  3
  •   CPerkins    15 年前

    这种方法的真正风险在于它会对不断变化的价值失去响应能力。

    是的,相对于大多数程序的运行时间,人们的年龄、体重和身高不会经常改变,但是他们确实会改变,例如,如果年龄改变了,而代码片段所在的对象仍然活着,那么最终的isoladenough可能会给出错误的答案。

    但我不相信 isEligible 人与人之间也是合适的,因为对什么是资格的了解似乎有更大的范围。必须问:什么资格?

    总之,在代码评审中,我可能建议您亲自添加方法。

    boolean isOldEnough (int minimumAge)  { return (this.getAge() > minimumAge); }
    

    等等。

        3
  •  1
  •   user92983    15 年前

    你的两个代码块是不相等的。

    有许多情况可以用来显示这个,但我将使用一个。假设person.getage()的最小年龄为true,person.gettall()引发了异常。

    在第一种情况下,表达式将执行if代码块,而第二种情况将引发异常。在可计算性理论中,当抛出异常时,这称为“底部元素”。已经证明,当使用渴望的评估语义(如第二个示例中)评估程序时,如果它终止(不解析为底部),那么保证了惰性的评估策略(第一个示例)将被终止。这是编程的一个重要原则。请注意,您不能自己编写Java的& & &函数。

    虽然gettall()方法不太可能引发异常,但不能将推理应用于一般情况。

        4
  •  0
  •   Jimmeh    15 年前

    我想支票可能属于个人类。您可以传递最小/最大值,但在我看来,调用person.iseligable()是更好的解决方案。

        5
  •  0
  •   Boris Pavlović    15 年前

    您可以更进一步,创建人员的子类型:

    Teenager extends Person
    ThirdAgePerson extends Person
    Kid extends Person
    

    子类将以自己的方式覆盖人的方法。

        6
  •  0
  •   defines    15 年前

    后一种情况的一个优点是,您将拥有isolandeough、istallenough和isnotthweight(sic)变量,这些变量稍后可在代码中重用。它也更容易阅读。

    您可能需要考虑将这些布尔检查抽象为它们自己的方法,或者将检查组合为一个方法。例如,person.isolandenough()方法,它将返回布尔检查的值。您甚至可以给它一个整数参数,这将是您的最小年龄,以提供更灵活的功能。

        7
  •  0
  •   djna    15 年前

    我认为这是个人品味的问题。我发现你的重构非常可读。

    在本部分中,我可以将整个测试重构为

    isThisPersonSuitable()
    

    方法。

    如果有很多这样的代码,我甚至可以创建一个个人口译员(可能是内部的)班,来容纳一个人并回答关于他们资格的问题。

    一般来说,我倾向于将可读性置于任何次要的性能考虑之上。

        8
  •  0
  •   matt b    15 年前

    唯一可能的负面影响是你失去了短路的好处。但实际上,只有当你的支票比其他支票贵得多时,这才真正意义重大,例如如果 person.getWeight() 是一个重要的操作,而不仅仅是访问器。

        9
  •  0
  •   Jay    15 年前

    我对您的构造没有任何异议,但在我看来,在这种情况下,通过简单地插入换行符,即

    if (person.getAge() > MINIMUM_AGE
      && person.getTall() > MAXIMUM_SIZE
      && person.getWeight < MAXIMUM_WEIGHT)
    {
      // do something
    }
    

    其他答案提出的更大的问题是这是否属于人的客体。我认为简单的答案是:如果有几个地方你做同样的测试,它属于个人。如果您在某些地方执行类似但不同的测试,那么它们属于调用类。

    例如,如果这是一个销售酒精的网站的系统,并且您有许多地方必须测试此人是否具有合法饮酒年龄,那么有一个person.islegaldringingage()函数是有意义的。如果唯一的因素是年龄,那么拥有一个最低饮酒年龄常数也可以达到同样的结果,我想,但是一旦涉及到其他逻辑,比如不同法律管辖区的不同法定饮酒年龄,或者有特殊情况或例外,那么它真的应该是一个成员职能。

    另一方面,如果你有一个地方,你检查某人是否超过18岁,其他地方,你检查他是否超过12岁,其他地方,你检查他是否超过65岁,等等,那么把这个功能推到人身上几乎没有什么好处。