程序员应该使用布尔变量来"记录"他们的代码吗?

fro*_*die 78 boolean conventions self-documenting

我正在阅读McConell的Code Complete,他讨论了使用布尔变量来记录代码.例如,而不是:

if((elementIndex < 0) || (MAX_ELEMENTS < elementIndex) || 
   (elementIndex == lastElementIndex)){
       ...
}
Run Code Online (Sandbox Code Playgroud)

他建议:

finished = ((elementIndex < 0) || (MAX_ELEMENTS < elementIndex));
repeatedEntry = (elementIndex == lastElementIndex);
if(finished || repeatedEntry){
   ...
}
Run Code Online (Sandbox Code Playgroud)

这让我感到逻辑,良好的实践和非常自我记录.但是,我对于经常使用这种技术犹豫不决,因为我几乎从未遇到过这种技术; 也许只是因为稀有而令人困惑.然而,我的经验还不是很大,所以我有兴趣听听程序员对这种技术的看法,我很想知道是否有人经常使用这种技术或者在阅读代码时经常看到它.这是一个值得采用的约定/风格/技术吗?其他程序员会理解并欣赏它,还是认为它很奇怪?

Ale*_*lli 54

将一个过于嵌套和复杂的表达式拆分为分配给局部变量的简单子表达式,然后重新组合在一起,这是一种非常常见且流行的技术 - 完全独立于子表达式和/或整体表达式是否为布尔值或几乎任何其他类型.通过精心挑选的名称,这种有品味的分解可以提高可读性,并且良好的编译器应该可以毫无困难地生成与原始复杂表达式相当的代码.

不具有的"转让"本身,比如Haskell的概念,甚至引进专业结构有些语言让你使用的技术(以下简称"给子表达式赋予一个名字" where在Haskell条款) -似乎预示着一些有问题的技术的受欢迎程度! - )

  • 如果它更简单,更容易阅读,我说这是一个非常明确的双赢案例:) (6认同)

Ode*_*ded 16

我已经使用过它,但通常将布尔逻辑包装成可重用的方法(如果从多个位置调用).

它有助于提高可读性,当逻辑发生变化时,它只需要在一个地方进行更改.

其他人会理解它并且不会觉得奇怪(除了那些只编写千行函数的人).


kem*_*002 9

我尝试尽可能地做到这一点.当然,您正在使用"额外的"代码,但与此同时,您正在描述为什么要对两个值进行比较.

在你的例子中,我查看代码,并问自己"好吧为什么看到这个值的人小于0?" 在第二个中,您清楚地告诉我,当发生这种情况时,某些进程已经完成.不要在第二个猜测你的意图是什么.

对我来说最重要的是当我看到一个方法时: DoSomeMethod(true); 为什么它会自动设置为true?它更具可读性

bool deleteOnCompletion = true;

DoSomeMethod(deleteOnCompletion);
Run Code Online (Sandbox Code Playgroud)

  • 我正是因为这个原因而不喜欢布尔参数.你最终得到像"createOrder(true,false,true,true,false)"这样的调用,这意味着什么?我更喜欢使用枚举,所以你说"createOrder(Source.MAIL_ORDER,BackOrder.NO,CustomOrder.CUSTOM,PayType.CREDIT)". (7认同)
  • 有了杰伊,你可以拥有在某些情况下肯定更清晰的优势.例如,使用PayType.如果它是布尔值,则参数可能被命名为isPayTypeCredit.你不知道改变是什么.使用枚举,您可以清楚地看到PayType是什么选项:Credit,Check,Cash并选择正确的选项. (2认同)

Pru*_*der 5

提供的样本:

finished = ((elementIndex < 0) || (MAX_ELEMENTS < elementIndex));
repeatedEntry = (elementIndex == lastElementIndex);
if(finished || repeatedEntry){
   ...
}
Run Code Online (Sandbox Code Playgroud)

也可以重写为使用方法,这提高了可读性并保留了布尔逻辑(正如Konrad指出的那样):

if (IsFinished(elementIndex) || IsRepeatedEntry(elementIndex, lastElementIndex)){
   ...
}

...

private bool IsFinished(int elementIndex) {
    return ((elementIndex < 0) || (MAX_ELEMENTS < elementIndex));
}

private bool IsRepeatedEntry(int elementIndex, int lastElementIndex) {
    return (elementIndex == lastElementIndex);
}
Run Code Online (Sandbox Code Playgroud)

当然,它是有代价的,这是两种额外的方法.如果你做了很多,它可能会使你的代码更具可读性,但你的类不那么透明.但话又说回来,你还可以将额外的方法转移到辅助类中.