TL; DR: no use argumentos booleanos.
Vea a continuación por qué son malos y cómo reemplazarlos (en negrita).
Los argumentos booleanos son muy difíciles de leer y, por lo tanto, difíciles de mantener. El principal problema es que el propósito es generalmente claro cuando lee la firma del método donde se nombra el argumento. Sin embargo, nombrar un parámetro generalmente no se requiere en la mayoría de los idiomas. Por lo tanto, tendrá antipatrones como RSACryptoServiceProvider#encrypt(Byte[], Boolean)
donde el parámetro booleano determina qué tipo de cifrado se utilizará en la función.
Entonces recibirá una llamada como:
rsaProvider.encrypt(data, true);
donde el lector tiene que buscar la firma del método simplemente para determinar qué demonios true
podría significar realmente. Por supuesto, pasar un número entero es igual de malo:
rsaProvider.encrypt(data, 1);
te diría lo mismo, o más bien: tan poco. Incluso si define constantes para el entero, los usuarios de la función pueden simplemente ignorarlas y seguir usando valores literales.
La mejor manera de resolver esto es usar una enumeración . Si tiene que pasar una enumeración RSAPadding
con dos valores: OAEP
o PKCS1_V1_5
entonces inmediatamente podrá leer el código:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Los booleanos solo pueden tener dos valores. Esto significa que si tiene una tercera opción, entonces tendría que refactorizar su firma. En general, esto no se puede realizar fácilmente si la compatibilidad con versiones anteriores es un problema, por lo que tendría que ampliar cualquier clase pública con otro método público. Esto es lo que finalmente hizo Microsoft cuando introdujeron RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
dónde usaron una enumeración (o al menos una clase que imitaba una enumeración) en lugar de un booleano.
Incluso puede ser más fácil usar un objeto completo o una interfaz como parámetro, en caso de que el parámetro en sí mismo deba parametrizarse. En el ejemplo anterior, el relleno OAEP en sí mismo podría parametrizarse con el valor hash para usarlo internamente. Tenga en cuenta que ahora hay 6 algoritmos hash SHA-2 y 4 algoritmos hash SHA-3, por lo que la cantidad de valores de enumeración puede explotar si solo usa una enumeración única en lugar de parámetros (esto es posiblemente lo próximo que Microsoft descubrirá) )
Los parámetros booleanos también pueden indicar que el método o clase no está bien diseñado. Al igual que con el ejemplo anterior: cualquier biblioteca criptográfica que no sea .NET no utiliza ningún indicador de relleno en la firma del método.
Casi todos los gurús del software que me gustan advierten contra los argumentos booleanos. Por ejemplo, Joshua Bloch advierte contra ellos en el muy apreciado libro "Effective Java". En general, simplemente no deben usarse. Se podría argumentar que podrían usarse si el caso es que hay un parámetro que es fácil de entender. Pero incluso entonces: Bit.set(boolean)
probablemente se implementa mejor utilizando dos métodos : Bit.set()
y Bit.unset()
.
Si no puede refactorizar directamente el código, puede definir constantes para al menos hacerlas más legibles:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
es mucho más legible que:
cipher.init(key, true);
incluso si prefieres tener:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
en lugar.