TL; DR: não use argumentos booleanos.
Veja abaixo por que eles são ruins e como substituí-los (em negrito).
Argumentos booleanos são muito difíceis de ler e, portanto, difíceis de manter. O principal problema é que o objetivo geralmente é claro quando você lê a assinatura do método em que o argumento é nomeado. No entanto, nomear um parâmetro geralmente não é necessário na maioria dos idiomas. Portanto, você terá antipadrões como RSACryptoServiceProvider#encrypt(Byte[], Boolean)
onde o parâmetro booleano determina que tipo de criptografia deve ser usado na função.
Então você receberá uma ligação como:
rsaProvider.encrypt(data, true);
onde o leitor precisa procurar a assinatura do método simplesmente para determinar o que diabos true
pode realmente significar. Passar um número inteiro é obviamente tão ruim quanto:
rsaProvider.encrypt(data, 1);
diria o mesmo - ou melhor: apenas o mínimo. Mesmo se você definir constantes a serem usadas para o número inteiro, os usuários da função poderão simplesmente ignorá-las e continuar usando valores literais.
A melhor maneira de resolver isso é usar uma enumeração . Se você precisar passar uma enumeração RSAPadding
com dois valores: OAEP
ou PKCS1_V1_5
poderá ler imediatamente o código:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Booleanos podem ter apenas dois valores. Isso significa que, se você tiver uma terceira opção, precisará refatorar sua assinatura. Geralmente, isso não pode ser realizado facilmente se a compatibilidade com versões anteriores for um problema; portanto, você precisará estender qualquer classe pública com outro método público. Foi o que a Microsoft finalmente fez quando eles introduziram RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
onde usavam uma enumeração (ou pelo menos uma classe imitando uma enumeração) em vez de um booleano.
Pode até ser mais fácil usar um objeto ou interface completo como parâmetro, caso o próprio parâmetro precise ser parametrizado. No exemplo acima, o preenchimento OAEP em si pode ser parametrizado com o valor de hash para uso interno. Observe que agora existem 6 algoritmos de hash SHA-2 e 4 algoritmos de hash SHA-3; portanto, o número de valores de enumeração pode explodir se você usar apenas uma única enumeração em vez de parâmetros (essa é possivelmente a próxima coisa que a Microsoft descobrirá )
Parâmetros booleanos também podem indicar que o método ou classe não foi projetado bem. Como no exemplo acima: qualquer biblioteca criptográfica que não seja a .NET não utiliza um sinalizador de preenchimento na assinatura do método.
Quase todos os gurus de software que eu gosto alertam contra argumentos booleanos. Por exemplo, Joshua Bloch adverte contra eles no livro muito apreciado "Java Efetivo". Em geral, eles simplesmente não devem ser usados. Você poderia argumentar que eles poderiam ser usados se houver um parâmetro fácil de entender. Mas mesmo assim: Bit.set(boolean)
provavelmente é melhor implementado usando dois métodos : Bit.set()
e Bit.unset()
.
Se você não puder refatorar diretamente o código, poderá definir constantes para, pelo menos, torná-las mais legíveis:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
é muito mais legível do que:
cipher.init(key, true);
mesmo se você preferir:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
em vez de.