TL; DR: Verwenden Sie keine booleschen Argumente.
Sehen Sie unten, warum sie schlecht sind und wie Sie sie ersetzen können (fett gedruckt).
Boolesche Argumente sind sehr schwer zu lesen und daher schwer zu pflegen. Das Hauptproblem ist, dass der Zweck im Allgemeinen klar ist, wenn Sie die Methodensignatur lesen, in der das Argument benannt ist. Die Benennung eines Parameters ist jedoch in den meisten Sprachen nicht erforderlich. Sie haben also Anti-Patterns, bei RSACryptoServiceProvider#encrypt(Byte[], Boolean)
denen der boolesche Parameter festlegt, welche Art von Verschlüsselung in der Funktion verwendet werden soll.
So erhalten Sie einen Anruf wie:
rsaProvider.encrypt(data, true);
wo der Leser die Signatur der Methode nachschlagen muss, um festzustellen, was zum Teufel true
eigentlich bedeuten könnte. Eine Ganzzahl zu übergeben ist natürlich genauso schlecht:
rsaProvider.encrypt(data, 1);
würde dir genauso viel sagen - oder vielmehr: genauso wenig. Selbst wenn Sie Konstanten definieren, die für die Ganzzahl verwendet werden sollen, können Benutzer der Funktion diese einfach ignorieren und weiterhin Literalwerte verwenden.
Der beste Weg, dies zu lösen, ist die Verwendung einer Aufzählung . Wenn Sie eine Enumeration RSAPadding
mit zwei Werten übergeben müssen: OAEP
oder PKCS1_V1_5
dann können Sie den Code sofort lesen:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Boolesche Werte können nur zwei Werte haben. Wenn Sie also eine dritte Option haben, müssen Sie Ihre Signatur überarbeiten. Im Allgemeinen kann dies nicht einfach durchgeführt werden, wenn Abwärtskompatibilität ein Problem ist, sodass Sie eine öffentliche Klasse mit einer anderen öffentlichen Methode erweitern müssen. Dies ist, was Microsoft schließlich tat, als sie einführten, RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
wo sie eine Aufzählung (oder zumindest eine Klasse, die eine Aufzählung nachahmt) anstelle eines Booleschen verwendeten.
Es kann sogar einfacher sein, ein vollständiges Objekt oder eine vollständige Schnittstelle als Parameter zu verwenden, falls der Parameter selbst parametrisiert werden muss. Im obigen Beispiel könnte die OAEP-Auffüllung selbst mit dem Hash-Wert parametrisiert werden, der intern verwendet wird. Beachten Sie, dass es jetzt 6 SHA-2-Hash-Algorithmen und 4 SHA-3-Hash-Algorithmen gibt, sodass die Anzahl der Aufzählungswerte explodieren kann, wenn Sie nur eine einzelne Aufzählung anstelle von Parametern verwenden (dies ist möglicherweise das nächste, was Microsoft herausfinden wird ).
Boolesche Parameter können auch darauf hinweisen, dass die Methode oder Klasse nicht gut entworfen wurde. Wie im obigen Beispiel: Jede andere kryptografische Bibliothek als .NET verwendet überhaupt kein Füllflag in der Methodensignatur.
Fast alle Software-Gurus, die ich mag, warnen vor booleschen Argumenten. Zum Beispiel warnt Joshua Bloch in dem hochgeschätzten Buch "Effective Java" davor. Im Allgemeinen sollten sie einfach nicht verwendet werden. Sie könnten argumentieren, dass sie verwendet werden könnten, wenn es einen Parameter gibt, der leicht zu verstehen ist. Aber selbst dann: Bit.set(boolean)
wird wahrscheinlich besser mit zwei Methoden implementiert : Bit.set()
und Bit.unset()
.
Wenn Sie den Code nicht direkt umgestalten können, können Sie Konstanten definieren , um sie zumindest lesbarer zu machen:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
ist viel lesbarer als:
cipher.init(key, true);
auch wenn du lieber hättest:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
stattdessen.