Tho*_*hel 122 enumeration boolean coding-style
我的一位同事表示,布尔作为方法论据是不可接受的.它们应由枚举代替.起初我没有看到任何好处,但他给了我一个例子.
什么更容易理解?
file.writeData( data, true );
Run Code Online (Sandbox Code Playgroud)
要么
enum WriteMode {
Append,
Overwrite
};
file.writeData( data, Append );
Run Code Online (Sandbox Code Playgroud)
现在我明白了!;-)
这绝对是一个例子,枚举作为第二个参数使代码更具可读性.
那么,您对此主题有何看法?
ska*_*man 130
Boolean表示"是/否"选项.如果你想表示"是/否",那么使用布尔值,它应该是不言自明的.
但是,如果它是两个选项之间的选择,两者都不是明显是或否,那么枚举有时可以更具可读性.
sim*_*mon 50
枚举还允许将来修改,您现在需要第三种选择(或更多).
Jer*_*que 32
使用最能模拟问题的那个.在您给出的示例中,枚举是更好的选择.但是,有时布尔值会更好.这对你更有意义:
lock.setIsLocked(True);
Run Code Online (Sandbox Code Playgroud)
要么
enum LockState { Locked, Unlocked };
lock.setLockState(Locked);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我可能会选择布尔选项,因为我认为它非常明确且毫不含糊,而且我很确定我的锁定不会超过两个状态.尽管如此,第二种选择是有效的,但不必要的复杂,恕我直言.
Tim*_*vis 13
我认为你自己几乎已经回答了这个问题,我认为最终的目的是让代码更具可读性,在这种情况下,枚举就是这样做的,IMO总是最好看看最终目标而不是一揽子规则,或许更多地考虑它作为指导,即代码通常在代码中比通用bool,int等更易读,但规则总会有例外.
Tho*_*n79 13
还记得Adlai Stevenson在古巴导弹危机期间向联合国大使佐林提出的问题吗?
"你现在正处于世界舆论的审判室,你可以回答 是或否.你否认[导弹]存在,我想知道我是否理解正确......我准备等待如果这是你的决定,直到地狱冻结为止我的回答."
如果您的方法中的标志具有这样的性质,您可以将其固定为二元决策,并且该决定永远不会变成三向或n向决策,那么请选择布尔值.适应症:你的旗帜叫做isXXX.
如果是模式切换,请不要将其设为布尔值.首先编写方法时,总会有一种模式比您想象的还要多.
一个多模式的困境就像困扰Unix一样,文件或目录今天可能拥有的权限模式会导致模式的奇怪双重含义,具体取决于文件类型,所有权等.
Sam*_*tte 13
我遇到的两个原因是坏事:
因为有些人会写下这样的方法:
ProcessBatch(true, false, false, true, false, false, true);
Run Code Online (Sandbox Code Playgroud)
这显然是不好的,因为它很容易混淆参数,你不知道通过查看你指定的内容.只有一个布尔不是太糟糕了.
因为通过简单的是/否分支来控制程序流可能意味着你有两个完全不同的函数,这些函数以一种笨拙的方式包装成一个.例如:
public void Write(bool toOptical);
Run Code Online (Sandbox Code Playgroud)
真的,这应该是两种方法
public void WriteOptical();
public void WriteMagnetic();
Run Code Online (Sandbox Code Playgroud)
因为这些代码可能完全不同; 他们可能不得不进行各种不同的错误处理和验证,甚至可能不同地格式化传出数据.你不能仅仅通过使用Write()甚至Write(Enum.Optical)(尽管如此你可以使用这些方法中的任何一种来调用内部方法WriteOptical/Mag).
我想这只是取决于.除了#1之外,我不会做太多关于它的交易.
Pas*_*ent 13
对我来说,使用布尔值和枚举都不是一个好方法.Robert C. Martin在他的清洁代码提示#12:消除布尔参数中非常清楚地捕获了这一点:
布尔参数大声声明该函数不止一件事.他们很混乱,应该被淘汰.
如果一个方法不止一个,你应该写两个不同的方法,例如在你的情况下:file.append(data)和file.overwrite(data).
使用枚举不会使事情更清楚.它没有改变任何东西,它仍然是一个旗帜论点.
布尔可能在具有命名参数的语言中可能没问题,例如Python和Objective-C,因为名称可以解释参数的作用:
file.writeData(data, overwrite=true)
Run Code Online (Sandbox Code Playgroud)
要么:
[file writeData:data overwrite:YES]
Run Code Online (Sandbox Code Playgroud)
枚举有一定的好处,但您不应该只是用枚举替换所有布尔值。在很多地方,真/假实际上是表示正在发生的事情的最佳方式。
然而,使用它们作为方法参数有点可疑,因为如果不深入研究它们应该做什么,你就无法看到它们,因为它们让你看到 true/false 的实际含义
[编辑2022年的现状]
在现代 C# 或支持此功能的其他语言中,最好的方法是使用命名参数:
var worker = new BackgroundWorker(workerReportsProgress: true);
Run Code Online (Sandbox Code Playgroud)
如果您的语言不允许命名参数,那么您可能会发现属性也是一个合理的解决方案
[2008年的原始答案留给后人]
属性(尤其是 C#3 对象初始值设定项)或关键字参数(如 ruby 或 python)是一种更好的方法,可以帮助您使用布尔参数。
C# 示例:
var worker = new BackgroundWorker { WorkerReportsProgress = true };
Run Code Online (Sandbox Code Playgroud)
红宝石示例
validates_presence_of :name, :allow_nil => true
Run Code Online (Sandbox Code Playgroud)
Python示例
connect_to_database( persistent=true )
Run Code Online (Sandbox Code Playgroud)
我唯一能想到的布尔方法参数是正确的做法是在 java 中,在那里你既没有属性也没有关键字参数。这是我讨厌java的原因之一:-(