7

我在阅读其他人的代码时遇到了很多标志,

if (condition1) 
    var1 = true
else
    var1 = false

然后后来,

if (var1 == true)
    // do something.

有很多这样的旗帜。我很想知道,在代码中经常使用标志是否可取?

4

14 回答 14

13

这:

if (condition1)
   var1= true;
else
   var1 = false;

是经典的写得不好的代码。
相反,你应该写:

var1 = condition1;

是的,标志对于使代码更具可读性并且可能更快非常有用。

于 2009-04-30T07:18:22.970 回答
7

建议如果condition1是相当复杂的东西——比如if (A && (B || C) && !D)或包含大量开销(if (somethingTimeConsumingThatWontChange())),那么存储该结果而不是复制粘贴代码是有意义的。

如果condition1只是一个简单的比较,那么不,我不会使用标志。

于 2009-04-30T07:10:06.593 回答
4

这是相当主观的,并且取决于代码的其余部分。你所说的“旗帜”有它们的位置。

于 2009-04-30T07:09:26.190 回答
2

首先,这段代码应该是这样的:

var1 = condition1;

if( var1 )

// No need to compare *true* to *true* when you're looking for *true*

至于标志的数量,有更优雅的代码分支方式。例如,在使用 javascript 时,您可以执行以下操作:

var methodName = someFunctionThatReturnsAString();

// assuming you name the method according to what's returned
myObject[ methodName ]();

代替

if( someFunctionThatReturnsAString === 'myPreferedMethod' ){
    myObject.myPreferedMethod();
}else{
    myObject.theOtherMethod();
}

如果您使用的是强类型语言,多态是您的朋友。我认为该技术被称为多态调度

于 2009-04-30T07:17:45.873 回答
2

我记得重构书中的这个Replace Temp var with Query 方法。我认为这种重构将使代码更具可读性,但是,我同意它可能会在查询方法昂贵时影响性能......(但是,也许可以将查询方法放在自己的类中,并且可以缓存结果进入那个班级)。

于 2009-04-30T07:22:32.133 回答
2

这个问题有点笼统。答案取决于您想做什么以及您希望它使用哪种语言。假设一个 OO 上下文比可能有更好的方法。

如果条件是某个对象状态的结果,那么“标志”应该是对象本身的属性。如果这是正在运行的应用程序的一个条件,并且您有很多这些东西,那么您可能应该考虑使用状态模式/状态机。

于 2009-04-30T07:24:26.450 回答
2

标志非常有用 - 但要给它们起合理的名称,例如在它们的名称中使用“Is”或类似的名称。

例如,比较:

if(Direction)    {/* do something */}
if(PowerSetting) {/* do something else */}

和:

if(DirectionIsUp) {/* do something */}
if(PowerIsOn)     {/* do something else */}
于 2009-04-30T17:26:51.087 回答
1

如果它是可读的并且可以完成工作,那么它没有任何问题。只需使用“has”和“is”前缀使其更具可读性:

var $isNewRecord;
var $hasUpdated;

if ($isNewRecord)
{
}

if ($hasUpdated)
{
}
于 2009-04-30T07:48:12.273 回答
0

这取决于条件和使用次数。无论如何,重构为函数(如果条件计算缓慢,最好缓存结果)可能会给你更多可读的代码。

例如考虑一下:

def checkCondition():
  import __builtin__ as cached
  try:
      return cached.conditionValue
  except NameError:
      cached.conditionValue = someSlowFunction()
      return cached.conditionValue

至于编码风格:

if (condition1)
   var1= true
else
   var1 = false

我讨厌那种代码。它应该是简单的:

var1 = condition1

或者如果你想确保结果是布尔值:

var1 = bool(condition1)

如果(var1 == 真)

再次。糟糕的编码风格。它的:

if (var1)
于 2009-04-30T07:50:57.197 回答
0

请记住,该代码可以更易读地编写为

var1 = condition1

,如果使用得当,这个赋值有一些有用的属性。一个用例是命名一个复杂的计算而不将其分解为一个函数:

user_is_on_fire = condition_that_holds_when_user_is_on_fire

这允许人们解释使用条件来表示什么,这通常从裸条件中并不明显。

如果评估条件代价高昂(或有副作用),则可能还需要在本地存储结果而不是重新评估条件。

一些警告:命名错误的标志会降低代码的可读性。远离使用它们的地方设置的标志也是如此。此外,人们想要使用标志这一事实是一种代码味道,表明人们应该考虑将条件分解成一个函数。

D'A

于 2009-04-30T07:59:26.427 回答
0

当您使用预 OO 语言工作时,将其称为标志。它们对于参数化一段代码的行为很有用。

但是,您很快就会发现代码难以遵循。当您通过例如提供对可变功能的引用来抽象出差异时,阅读/更改/维护会更容易。

在函数是一等公民的语言中(例如 Javascript、Haskell、Lisp,...),这是轻而易举的事。

在 OO 语言中,您可以实现一些设计模式,如抽象工厂、策略/策略、...

我个人认为太多开关是代码异味。

于 2009-04-30T08:00:24.647 回答
0

我不喜欢标志的地方是当它们被称为标志时,没有任何评论。

例如

void foo(...){

     bool flag;

    //begin some weird looking code

    if (something)
       [...]
      flag = true; 
 }

他们试图反对代码可重复性。在最初的程序员离开后数月/数年必须阅读它的可怜人将很难理解它最初的目的是什么。

但是,如果标志变量有一个代表名称,那么我认为它们是可以的,只要明智地使用(参见其他回复)。

于 2009-04-30T17:36:21.267 回答
0

是的,这只是愚蠢的无意义代码。

您可以将所有这些简化为:

if (condition1)
{
  // do something
}
于 2009-04-30T17:46:33.990 回答
0

这是我的看法。使用标志的代码:

...
if (dogIsBarking && smellsBad) {
  cleanupNeeded = true;
}
doOtherStuff();
... many lines later
if (cleanupNeeded) {
  startCleanup();
}
...

很不干净。程序员只是碰巧按照他的大脑告诉他的顺序编写代码。他只是在一个随机的地方添加了代码,以提醒自己稍后需要清理......他为什么不这样做:

...
doOtherStuff();
... many lines later
if (dogIsBarking && smellsBad) {
  startCleanup();
}
...

并且,根据 Robert Martin(清洁代码)的建议,可以将逻辑重构为更有意义的方法:

...
doSomeStuff();
... many lines later
if (dogTookADump()) {
  startCleanup();
}
...
boolean dogTookADump() {
  return (dogIsBarking && smellsBad);
}

所以,我已经看到很多代码可以遵循上面的简单规则,但人们却无缘无故地添加复杂性和标志!现在,有些情况下可能需要标志,但在大多数情况下,它们是程序员从过去继承下来的一种风格。

于 2016-04-18T18:25:33.223 回答