TL; DR:请勿使用布尔参数。
参见下文,了解它们的坏处以及如何更换它们(粗体显示)。
布尔参数很难理解,因此很难维护。主要问题是,当您读取命名该参数的方法签名时,目的通常很清楚。但是,大多数语言通常不需要命名参数。因此,您将拥有一些反模式,例如RSACryptoServiceProvider#encrypt(Byte[], Boolean)
boolean参数确定函数中将使用哪种加密方式。
因此,您将收到如下电话:
rsaProvider.encrypt(data, true);
读者必须在其中查找方法的签名,才能确定到底是什么true
意思。传递整数当然同样糟糕:
rsaProvider.encrypt(data, 1);
会告诉您或多或少:即使您定义了要用于整数的常量,函数的用户也可能会忽略它们并继续使用文字值。
解决此问题的最佳方法是使用枚举。如果您必须传递RSAPadding
带有两个值的枚举:OAEP
否则PKCS1_V1_5
您将立即能够读取代码:
rsaProvider.encrypt(data, RSAPadding.OAEP);
布尔值只能有两个值。这意味着,如果您有第三种选择,则必须重构签名。通常,如果向后兼容是一个问题,则无法轻松执行,因此您必须使用其他公共方法扩展任何公共类。这是Microsoft最终在引入RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
使用枚举(或至少是模仿枚举的类)而不是布尔值的地方时所做的事情。
如果需要对参数本身进行参数化,则甚至可以更容易地使用完整的对象或接口作为参数。在上面的示例中,可以使用散列值对OAEP填充自身进行参数化,以供内部使用。请注意,现在有6种SHA-2哈希算法和4种SHA-3哈希算法,因此,如果仅使用单个枚举而不是参数,则枚举值的数量可能会激增(这可能是Microsoft下一步要发现的事情) )。
布尔参数也可能表示该方法或类的设计不正确。与上面的示例一样:.NET以外的任何加密库都根本不在方法签名中使用填充标志。
我喜欢警告几乎所有的软件专家都反对布尔参数。例如,约书亚·布洛赫(Joshua Bloch)在备受赞誉的《有效Java》一书中警告他们。通常,不应使用它们。您可能会争辩说,如果存在一个易于理解的参数,则可以使用它们。但是即使这样:Bit.set(boolean)
最好使用以下两种方法来更好地实现:Bit.set()
和Bit.unset()
。
如果您不能直接重构代码,则可以定义常量以至少使它们更具可读性:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
比以下内容更具可读性:
cipher.init(key, true);
即使您希望:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
代替。