TL; DR: nie używaj argumentów boolowskich.
Zobacz poniżej, dlaczego są złe i jak je wymienić (pogrubioną twarzą).
Argumenty logiczne są bardzo trudne do odczytania, a zatem trudne do utrzymania. Głównym problemem jest to, że cel jest ogólnie jasny, gdy czytasz sygnaturę metody, w której argument jest nazwany. Jednak w większości języków nazwa parametru nie jest na ogół wymagana. Będziesz miał więc anty-wzorce, takie jak RSACryptoServiceProvider#encrypt(Byte[], Boolean)
gdzie parametr boolowski określa, jakiego rodzaju szyfrowanie ma być użyte w funkcji.
Otrzymasz połączenie takie jak:
rsaProvider.encrypt(data, true);
gdzie czytelnik musi sprawdzić podpis metody, aby ustalić, co do cholery true
może znaczyć. Przekazywanie liczby całkowitej jest oczywiście równie złe:
rsaProvider.encrypt(data, 1);
powiedziałbym ci tyle samo - a raczej: tak samo mało. Nawet jeśli zdefiniujesz stałe, które będą używane dla liczby całkowitej, użytkownicy funkcji mogą po prostu je zignorować i nadal używać wartości literalnych.
Najlepszym sposobem rozwiązania tego jest użycie wyliczenia . Jeśli musisz przekazać wyliczenie RSAPadding
z dwiema wartościami: OAEP
lub PKCS1_V1_5
wtedy od razu będziesz w stanie odczytać kod:
rsaProvider.encrypt(data, RSAPadding.OAEP);
Wartości logiczne mogą mieć tylko dwie wartości. Oznacza to, że jeśli masz trzecią opcję, musisz przefakturować swój podpis. Zasadniczo nie można tego łatwo wykonać, jeśli problemem jest kompatybilność wsteczna, dlatego trzeba rozszerzyć dowolną klasę publiczną za pomocą innej metody publicznej. To właśnie zrobił Microsoft, kiedy przedstawił, RSACryptoServiceProvider#encrypt(Byte[], RSAEncryptionPadding)
gdzie użył wyliczenia (lub przynajmniej klasy naśladującej wyliczenie) zamiast wartości logicznej.
Użycie pełnego obiektu lub interfejsu jako parametru może być nawet łatwiejsze na wypadek, gdyby sam parametr musiał zostać sparametryzowany. W powyższym przykładzie sam dopełnienie OAEP można sparametryzować za pomocą wartości skrótu do użycia wewnętrznego. Zauważ, że jest teraz 6 algorytmów mieszających SHA-2 i 4 algorytmy mieszające SHA-3, więc liczba wartości wyliczeniowych może wybuchnąć, jeśli użyjesz tylko jednego wyliczenia zamiast parametrów (jest to prawdopodobnie następna rzecz, którą Microsoft się dowie ).
Parametry boolowskie mogą również wskazywać, że metoda lub klasa nie została dobrze zaprojektowana. Podobnie jak w powyższym przykładzie: żadna biblioteka kryptograficzna inna niż .NET nie używa flagi wypełnienia w sygnaturze metody.
Prawie wszyscy guru oprogramowania, których lubię, ostrzegają przed argumentami logicznymi. Na przykład Joshua Bloch ostrzega przed nimi w bardzo cenionej książce „Effective Java”. Zasadniczo nie należy ich używać. Można argumentować, że można ich użyć, jeśli przypadek jest taki, że jeden parametr jest łatwy do zrozumienia. Ale nawet wtedy: Bit.set(boolean)
prawdopodobnie lepiej jest go zaimplementować przy użyciu dwóch metod : Bit.set()
i Bit.unset()
.
Jeśli nie możesz bezpośrednio refaktoryzować kodu, możesz zdefiniować stałe, aby przynajmniej uczynić je bardziej czytelnymi:
const boolean ENCRYPT = true;
const boolean DECRYPT = false;
...
cipher.init(key, ENCRYPT);
jest znacznie bardziej czytelny niż:
cipher.init(key, true);
nawet jeśli wolisz:
cipher.initForEncryption(key);
cipher.initForDecryption(key);
zamiast.