最佳实践布尔分配


10

我在另一个开发人员接手的程序中遇到以下条件:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

我相信这段代码是多余的和丑陋的,因此我根据比较将其更改为我认为是简单的布尔分配:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

看到此消息后,查看我的代码的人评论说,尽管我的更改在功能上是正确的,但可能会使其他人困惑。他认为使用三元运算符可以使此分配更加清晰,而我不喜欢添加更多的冗余代码:

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE) ? true : false;

他的理由是,如果这样做会使另一个开发人员不得不停下来并确切地想出自己所做的事情,那么以最简洁的方式做某事是不值得的。

真正的问题是,这三种为布尔值赋值的方法中哪一种obj.NeedsChange最清晰,最可维护?


25
第三种形式很荒谬;它只是说明第二种形式中应该已经显而易见的内容。
罗伯特·哈维

6
这完全取决于个人喜好。我们可以假装其他方式,但是由于它们在功能上都是等效的,因此可以归结为style。当然,在可读性方面存在差异,但我的“可读且透明”可能是您的“钝角和不透明”
MetaFight 2015年

3
@scriptin 5-8行v 1行比首选项更重要,因此5-8衬里通常更清晰,更好。在这个简单的示例中,我更喜欢1条线,但是总的来说,我看到太多10条衬里被混淆成1条衬里以保持舒适。鉴于此,我永远不会抱怨变体1,它可能不是很漂亮,但它所做的工作同样清晰明了。
gbjbaanb 2015年

4
选项1和3对我说:“作者并不真正了解布尔逻辑”。
15年

2
如果需要经常根据值设置断点,则变体1可能会有用。
2015年

Answers:


39

我更喜欢2,但是我可能会对其进行一些调整:

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

对我来说,括号使该行更易于解析,并且一目了然,您将分配比较结果,而不执行双重分配。我不确定为什么会这样(因为我暂时无法想到括号实际上会阻止双重赋值的语言),但是如果您必须令您的审稿人满意,那么也许这是一个可以接受的折衷方案。


4
这是正确的答案-尽管问题中的代码是正确的,但添加方括号确实会告诉读者它不是作业。如果您正在快速浏览代码,则括号内会为您提供即时的额外信息,使您无需再仔细查看代码是否像那样,并且不是偶然的错误。例如,假设该行是a = b == c,您是要分配一个布尔值还是要给b和a分配c。
gbjbaanb 2015年

括号会阻止在Python中进行双重分配。即使在不阻止双重赋值的语言中,括号也绝对有助于表明您正在处理两种运算。
user2357112支持Monica

23

变体1很容易理解,但这是它的唯一优点。我自动假设,像这样编写的任何人都不会真正理解布尔值的含义,并且会在许多其他方面编写类似的婴儿代码。

变体2是我将始终写并且希望阅读的东西。我认为,任何对此习语感到困惑的人都不应成为软件的专业作家。

变体3结合了1和2的缺点。


好吧,变体1与变体2共享优势...
重复数据删除器2015年

1
+1为婴儿代码。我多年来一直在寻找这样的代码,只是缺少正确的词来识别它。
Lilienthal

1
我对诸如变式1这样的代码的第一个假设是,过去某个时刻的两个分支更加复杂,并且有人在重构时没有注意。但是,如果这是第一次写作时的样子,那么我同意“不理解布尔值”
Izkata 2015年

13

任何时候,代码比需要触发都要复杂,“这应该做什么?” 读者闻到。

例如,第一个示例让我感到奇怪,“是否在某些时候,if / else语句中还有其他功能?”

示例(2)简单,清晰,并且完全满足需要。我读了一下,立即了解了代码的作用。

(3)中多余的绒毛使我想知道为什么作者以这种方式而不是(2)那样写。这里应该是一个原因,但在这种情况下,似乎没有要,所以它不是在所有有用的和难以阅读,因为这个语法表明目前的东西是不存在的。尝试了解存在的内容(什么都不存在时)会使代码难以阅读。


2

可以很容易地看出,变量2和变量1是通过一系列显而易见且简单的重构相关的:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

在这里,我们有不必要的代码重复,我们可以考虑分配:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE)
{
    true
}
else
{
    false
}

或更简洁地写:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE) true else false

现在,应该立即显而易见的是,如果条件为true则将分配true,如果条件为false则将分配false,IOW它将简单地分配条件的值,即等于

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE

变体1和3是典型的菜鸟代码,由不了解比较返回值的人编写。


我会在您的if(...)... false部分之前添加一个注释,然后在代码清晰和更好的代码中进行简单的扫描。
DaveM

2

虽然您的编程应该倾向于显式而非隐式“好像最终维护您的代码的人将是一个暴力的精神病患者,知道您的住所”,但是可以假设一些基本的事情,您的心理继任者将胜任。

其中之一是他使用的语言的语法

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

对于任何了解C / C ++ / C#/ Java / Javascript语法的人来说,这都很清楚。

它也比8行更具可读性。

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

而且不易出错

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.Needschange = false;
}

它比添加不必要的字符更好,就像您半忘了该语言的语法一样:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE ? true : false;

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE);

我认为许多语言的类C语法存在很多错误:操作顺序不一致,左/右关联性不一致,符号使用过多,花括号/缩进重复,三元运算符,中缀表示法等。

但是解决方案不是发明自己的专有版本。当每个人都创造自己的东西时,那就是疯狂。


通常,使Real World TM代码无法读取的第一件事就是数量。

在一个非病理性的200行程序和一个几乎相同的1,600行程序之间,较短的程序几乎总是更容易解析和理解。随时欢迎您的更改。


1

大部分开发人员一眼就能理解第二种形式。我认为第一种形式的简化根本没有必要。

您可以通过添加空格和花括号来提高可读性,例如:

obj.NeedsChange =    obj.Performance <= LOW_PERFORMANCE;

要么

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

正如Jacob Raihle所提到的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.