我在阅读其他人的代码时遇到了很多标志,
if (condition1)
var1 = true
else
var1 = false
然后后来,
if (var1 == true)
// do something.
有很多这样的旗帜。我很想知道,在代码中经常使用标志是否可取?
我在阅读其他人的代码时遇到了很多标志,
if (condition1)
var1 = true
else
var1 = false
然后后来,
if (var1 == true)
// do something.
有很多这样的旗帜。我很想知道,在代码中经常使用标志是否可取?
这:
if (condition1)
var1= true;
else
var1 = false;
是经典的写得不好的代码。
相反,你应该写:
var1 = condition1;
是的,标志对于使代码更具可读性并且可能更快非常有用。
建议如果condition1
是相当复杂的东西——比如if (A && (B || C) && !D)
或包含大量开销(if (somethingTimeConsumingThatWontChange())
),那么存储该结果而不是复制粘贴代码是有意义的。
如果condition1
只是一个简单的比较,那么不,我不会使用标志。
这是相当主观的,并且取决于代码的其余部分。你所说的“旗帜”有它们的位置。
首先,这段代码应该是这样的:
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();
}
如果您使用的是强类型语言,多态是您的朋友。我认为该技术被称为多态调度
我记得重构书中的这个Replace Temp var with Query 方法。我认为这种重构将使代码更具可读性,但是,我同意它可能会在查询方法昂贵时影响性能......(但是,也许可以将查询方法放在自己的类中,并且可以缓存结果进入那个班级)。
这个问题有点笼统。答案取决于您想做什么以及您希望它使用哪种语言。假设一个 OO 上下文比可能有更好的方法。
如果条件是某个对象状态的结果,那么“标志”应该是对象本身的属性。如果这是正在运行的应用程序的一个条件,并且您有很多这些东西,那么您可能应该考虑使用状态模式/状态机。
标志非常有用 - 但要给它们起合理的名称,例如在它们的名称中使用“Is”或类似的名称。
例如,比较:
if(Direction) {/* do something */}
if(PowerSetting) {/* do something else */}
和:
if(DirectionIsUp) {/* do something */}
if(PowerIsOn) {/* do something else */}
如果它是可读的并且可以完成工作,那么它没有任何问题。只需使用“has”和“is”前缀使其更具可读性:
var $isNewRecord;
var $hasUpdated;
if ($isNewRecord)
{
}
if ($hasUpdated)
{
}
这取决于条件和使用次数。无论如何,重构为函数(如果条件计算缓慢,最好缓存结果)可能会给你更多可读的代码。
例如考虑一下:
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)
请记住,该代码可以更易读地编写为
var1 = condition1
,如果使用得当,这个赋值有一些有用的属性。一个用例是命名一个复杂的计算而不将其分解为一个函数:
user_is_on_fire = condition_that_holds_when_user_is_on_fire
这允许人们解释使用条件来表示什么,这通常从裸条件中并不明显。
如果评估条件代价高昂(或有副作用),则可能还需要在本地存储结果而不是重新评估条件。
一些警告:命名错误的标志会降低代码的可读性。远离使用它们的地方设置的标志也是如此。此外,人们想要使用标志这一事实是一种代码味道,表明人们应该考虑将条件分解成一个函数。
D'A
当您使用预 OO 语言工作时,将其称为标志。它们对于参数化一段代码的行为很有用。
但是,您很快就会发现代码难以遵循。当您通过例如提供对可变功能的引用来抽象出差异时,阅读/更改/维护会更容易。
在函数是一等公民的语言中(例如 Javascript、Haskell、Lisp,...),这是轻而易举的事。
在 OO 语言中,您可以实现一些设计模式,如抽象工厂、策略/策略、...
我个人认为太多开关是代码异味。
我不喜欢标志的地方是当它们被称为标志时,没有任何评论。
例如
void foo(...){
bool flag;
//begin some weird looking code
if (something)
[...]
flag = true;
}
他们试图反对代码可重复性。在最初的程序员离开后数月/数年必须阅读它的可怜人将很难理解它最初的目的是什么。
但是,如果标志变量有一个代表名称,那么我认为它们是可以的,只要明智地使用(参见其他回复)。
是的,这只是愚蠢的无意义代码。
您可以将所有这些简化为:
if (condition1)
{
// do something
}
这是我的看法。使用标志的代码:
...
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);
}
所以,我已经看到很多代码可以遵循上面的简单规则,但人们却无缘无故地添加复杂性和标志!现在,有些情况下可能需要标志,但在大多数情况下,它们是程序员从过去继承下来的一种风格。