TL; DR: non usare argomenti booleani.
Vedi sotto perché sono cattivi e come sostituirli (in grassetto).
Gli argomenti booleani sono molto difficili da leggere e quindi difficili da mantenere. Il problema principale è che lo scopo è generalmente chiaro quando leggi la firma del metodo in cui l'argomento è chiamato. Tuttavia, la denominazione di un parametro non è generalmente richiesta nella maggior parte delle lingue. Quindi avrai anti-pattern come RSACryptoServiceProvider#encrypt(Byte[], Boolean)
dove il parametro booleano determina quale tipo di crittografia deve essere usato nella funzione.
Quindi riceverai una chiamata come:
rsaProvider.encrypt(data, true);
dove il lettore deve cercare la firma del metodo semplicemente per determinare cosa diavolo true
potrebbe effettivamente significare. Passare un numero intero è ovviamente altrettanto negativo:
rsaProvider.encrypt(data, 1);
te lo direi altrettanto - o meglio: altrettanto poco. Anche se si definiscono le costanti da utilizzare per l'intero, gli utenti della funzione possono semplicemente ignorarle e continuare a utilizzare i valori letterali.
Il modo migliore per risolverlo è utilizzare un'enumerazione . Se devi passare un enum RSAPadding
con due valori: OAEP
o PKCS1_V1_5
allora sarai immediatamente in grado di leggere il codice:
rsaProvider.encrypt(data, RSAPadding.OAEP);
I booleani possono avere solo due valori. Ciò significa che se si dispone di una terza opzione, è necessario riformattare la firma. Generalmente questo non può essere facilmente eseguito se la compatibilità con le versioni precedenti è un problema, quindi dovresti estendere qualsiasi classe pubblica con un altro metodo pubblico. Questo è ciò che Microsoft ha fatto alla fine quando ha introdotto il RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
punto in cui utilizzava un'enumerazione (o almeno una classe che imita un'enumerazione) anziché un valore booleano.
Potrebbe anche essere più semplice utilizzare un oggetto completo o un'interfaccia come parametro, nel caso in cui il parametro stesso debba essere parametrizzato. Nell'esempio sopra, il padding OAEP stesso potrebbe essere parametrizzato con il valore hash da usare internamente. Si noti che ora ci sono 6 algoritmi hash SHA-2 e 4 algoritmi hash SHA-3, quindi il numero di valori di enumerazione potrebbe esplodere se si utilizza solo una singola enumerazione anziché parametri (questa è probabilmente la prossima cosa che Microsoft scoprirà ).
I parametri booleani possono anche indicare che il metodo o la classe non è progettato correttamente. Come nell'esempio sopra: qualsiasi libreria crittografica diversa da quella .NET non usa affatto un flag di padding nella firma del metodo.
Quasi tutti i guru del software che mi piacciono mettono in guardia contro argomenti booleani. Ad esempio, Joshua Bloch mette in guardia contro di loro nel libro molto apprezzato "Effective Java". In generale, semplicemente non dovrebbero essere usati. Si potrebbe sostenere che potrebbero essere usati se esiste un parametro che è facile da capire. Ma anche allora: Bit.set(boolean)
è probabilmente meglio implementato usando due metodi : Bit.set()
e Bit.unset()
.
Se non è possibile refactificare direttamente il codice, è possibile definire costanti per renderle almeno più leggibili:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
è molto più leggibile di:
cipher.init(key, true);
anche se preferiresti avere:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
anziché.