TL;DR: don't use boolean arguments.
See below why they are bad, and how to replace them (in bold face).
Boolean arguments are very hard to read, and thus difficult to maintain. The main problem is that the purpose is generally clear when you read the method signature where the argument is named. However, naming a parameter is generally not required in most languages. So you will have anti-patterns like RSACryptoServiceProvider#encrypt(Byte[], Boolean)
where the boolean parameter determines what kind of encryption is to be used in the function.
So you will get a call like:
rsaProvider.encrypt(data, true);
where the reader has to lookup the method's signature simply to determine what the hell true
could actually mean. Passing an integer is of course just as bad:
rsaProvider.encrypt(data, 1);
would tell you just as much - or rather: just as little. Even if you define constants to be used for the integer then users of the function may simply ignore them and keep using literal values.
The best way to solve this is to use an enumeration. If you have to pass an enum RSAPadding
with two values: OAEP
or PKCS1_V1_5
then you would immediately be able to read the code:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Booleans can only have two values. This means that if you have a third option, then you'd have to refactor your signature. Generally this cannot be easily performed if backwards compatibility is an issue, so you'd have to extend any public class with another public method. This is what Microsoft finally did when they introduced RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
where they used an enumeration (or at least a class mimicking an enumeration) instead of a boolean.
It may even be easier to use a full object or interface as parameter, in case the parameter itself needs to be parameterized. In the above example OAEP padding itself could be parameterized with the hash value to use internally. Note that there are now 6 SHA-2 hash algorithms and 4 SHA-3 hash algorithms, so the number of enumeration values may explode if you only use a single enumeration rather than parameters (this is possibly the next thing Microsoft is going to find out).
Boolean parameters may also indicate that the method or class is not designed well. As with the example above: any cryptographic library other than the .NET one doesn't use a padding flag in the method signature at all.
Almost all software gurus that I like warn against boolean arguments. For instance, Joshua Bloch warns against them in the highly appreciated book "Effective Java". In general they should simply not be used. You could argue that they could be used if the case that there is one parameter that is easy to understand. But even then: Bit.set(boolean)
is probably better implemented using two methods: Bit.set()
and Bit.unset()
.
If you cannot directly refactor the code you could define constants to at least make them more readable:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
is much more readable than:
cipher.init(key, true);
even if you'd rather have:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
instead.