TL; DR: n'utilisez pas d'arguments booléens.
Voir ci-dessous pourquoi ils sont mauvais et comment les remplacer (en caractères gras).
Les arguments booléens sont très difficiles à lire et donc difficiles à maintenir. Le problème principal est que l'objectif est généralement clair lorsque vous lisez la signature de la méthode où l'argument est nommé. Cependant, nommer un paramètre n'est généralement pas requis dans la plupart des langues. Ainsi, vous aurez des anti-modèles comme RSACryptoServiceProvider#encrypt(Byte[], Boolean)
où le paramètre booléen détermine quel type de cryptage doit être utilisé dans la fonction.
Donc, vous recevrez un appel comme:
rsaProvider.encrypt(data, true);
où le lecteur doit rechercher la signature de la méthode simplement pour déterminer ce que l'enfer true
pourrait réellement vouloir dire. Passer un entier est bien sûr tout aussi mauvais:
rsaProvider.encrypt(data, 1);
vous en dirait autant - ou plutôt: tout aussi peu. Même si vous définissez des constantes à utiliser pour l'entier, les utilisateurs de la fonction peuvent simplement les ignorer et continuer à utiliser des valeurs littérales.
La meilleure façon de résoudre ce problème consiste à utiliser une énumération . Si vous devez passer une énumération RSAPadding
avec deux valeurs: OAEP
ou PKCS1_V1_5
alors vous pourrez immédiatement lire le code:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Les booléens ne peuvent avoir que deux valeurs. Cela signifie que si vous avez une troisième option, vous devrez alors refactoriser votre signature. Généralement, cela ne peut pas être facilement réalisé si la compatibilité avec les versions antérieures pose un problème. Vous devez donc étendre toute classe publique avec une autre méthode publique. C'est ce que Microsoft a finalement fait quand ils ont introduit RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
où ils utilisaient une énumération (ou au moins une classe imitant une énumération) au lieu d'un booléen.
Il peut même être plus facile d’utiliser un objet complet ou une interface en tant que paramètre, au cas où le paramètre lui-même aurait besoin d’être paramétré. Dans l'exemple ci-dessus, le rembourrage OAEP lui-même pourrait être paramétré avec la valeur de hachage à utiliser en interne. Notez qu’il existe maintenant 6 algorithmes de hachage SHA-2 et 4 algorithmes de hachage SHA-3. Par conséquent, le nombre de valeurs d’énumération peut exploser si vous utilisez une seule énumération plutôt que des paramètres (c’est peut-être la prochaine chose que Microsoft va découvrir. ).
Les paramètres booléens peuvent également indiquer que la méthode ou la classe n'est pas bien conçue. Comme dans l'exemple ci-dessus: aucune bibliothèque cryptographique autre que la librairie .NET n'utilise du tout d'indicateur de remplissage dans la signature de la méthode.
Presque tous les gourous du logiciel que j'aime mettent en garde contre les arguments booléens. Par exemple, Joshua Bloch les met en garde dans le livre très apprécié "Effective Java". En général, ils ne devraient tout simplement pas être utilisés. Vous pourriez faire valoir qu'ils pourraient être utilisés s'il y avait un paramètre facile à comprendre. Mais même dans ce cas: il Bit.set(boolean)
est probablement préférable de mettre en œuvre deux méthodes : Bit.set()
et Bit.unset()
.
Si vous ne pouvez pas refactoriser directement le code, vous pouvez définir des constantes pour au moins les rendre plus lisibles:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
est beaucoup plus lisible que:
cipher.init(key, true);
même si vous préférez avoir:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
au lieu.