3 potężne techniki kodowania w celu usunięcia niechlujnych warunków
Przedstawia trzy potężne techniki kodowania w celu optymalizacji i uproszczenia złożonych struktur warunkowych, poprawiając jakość i utrzymywalność kodu.
Przedstawia trzy potężne techniki kodowania w celu optymalizacji i uproszczenia złożonych struktur warunkowych, poprawiając jakość i utrzymywalność kodu.
W tworzeniu oprogramowania często napotykamy na logikę kodu, która musi obsługiwać wiele scenariuszy. Jeśli nie zostaną one odpowiednio zarządzane, te logiki mogą łatwo przekształcić się w długie łańcuchy if-else lub ogromne instrukcje switch. Ten artykuł przedstawi kilka skutecznych technik optymalizacji tych struktur, poprawiając jakość i utrzymywalność kodu.
Załóżmy, że rozwijamy system uwierzytelniania użytkowników, który musi sprawdzać różne statusy użytkownika przed zezwoleniem na dostęp:
Ten kod ma oczywiste problemy strukturalne. Używa głęboko zagnieżdżonych struktur if-else, co sprawia, że kod jest trudny do odczytania i utrzymania. W miarę wzrostu liczby sprawdzanych warunków, poziom wcięć w kodzie się zwiększa, tworząc tak zwany kod "kształtu strzałki". Logika obsługi błędów jest rozproszona na różnych poziomach zagnieżdżeń, co nie sprzyja jednolitemu zarządzaniu. Co ważniejsze, główna logika kodu — przypadek, w którym dostęp jest dozwolony — jest pochowana głęboko w wielu warstwach warunkowych osądów, co brak intuicyjności. Ten styl kodowania nie tylko zmniejsza czytelność kodu, ale także zwiększa ryzyko błędów i utrudnia rozwijanie kodu.
Możemy zoptymalizować ten kod za pomocą podejścia "wczesny zwrot":
Stosując strategię "wczesny zwrot", z powodzeniem zoptymalizowaliśmy oryginalną strukturę kodu.
Ta metoda przynosi kilka ulepszeń:
Często napotykamy scenariusze, w których należy zwrócić różne wyniki w zależności od różnych danych wejściowych. Jeśli nie zostaną one odpowiednio obsłużone, te logiki mogą łatwo przekształcić się w długie łańcuchy if-else lub ogromne instrukcje switch. Na przykład na platformie e-commerce musimy zwrócić odpowiednie opisy statusu na podstawie różnych statusów zamówienia:
To jest typowy scenariusz zwracania różnych wyników na podstawie różnych przypadków. W miarę zwiększania się liczby przypadków, instrukcje switch lub sądy if-else stają się rozbudowane. Dodatkowo, w tym scenariuszu, jeśli użytkownicy muszą przetłumaczyć te statusy na inne języki, wymagałoby to modyfikacji ciała funkcji lub dodawania nowych funkcji, co wiązałoby się z dużymi kosztami utrzymania.
W tym przypadku możemy użyć metody tablicy przeszukiwania w celu optymalizacji kodu:
Po pierwsze, za pomocą obiektu Map do przechowywania relacji mapującej pomiędzy statusami a opisami, kod staje się bardziej zwięzły. Umożliwiliśmy także łatwe przenoszenie opisów statusu do plików konfiguracyjnych, co zapewnia wygodę internacjonalizacji i dynamicznych aktualizacji. Kiedy dodawane są nowe statusy, nie musimy modyfikować rdzenia logiki kodu; wystarczy dodać odpowiednie pary klucz-wartość w konfiguracji.
Podczas rozwijania dużych systemów oprogramowania często musimy wspierać wielu dostawców usług lub moduły funkcjonalne. Możemy rozważyć użycie programowania zorientowanego na interfejs na etapie projektowania oprogramowania, aby ułatwić późniejsze rozszerzenia, eliminując tym samym złożoność licznych warunkowych osądów wynikających z twardego kodowania w złożonych systemach.
Załóżmy, że rozwijamy wielojęzyczny system tłumaczeń, który musi obsługiwać różnych dostawców usług tłumaczeń. Jeśli nie weźmiemy pod uwagę programowania zorientowanego na interfejs na etapie projektowania, późniejsze rozszerzenia będą bardzo trudne:
Implementacja ta używa prostej i prymitywnej struktury if-else do wyboru dostawców tłumaczeń, co sprawia, że kod jest trudny do utrzymania i rozszerzenia. W miarę dodawania nowych dostawców tłumaczeń w przyszłości, istniejący kod musi być modyfikowany, a w miarę zwiększania liczby wspieranych dostawców tłumaczeń, kod stanie się rozbudowany i trudny do utrzymania. Jednocześnie ta złożona metoda jest również trudna do testowania jednostkowego, ponieważ nie jest łatwo symulować różnych dostawców tłumaczeń.
Aby rozwiązać te problemy, możemy użyć programowania zorientowanego na interfejs do optymalizacji kodu. Programowanie zorientowane na interfejs to ważny sposób realizacji polimorfizmu, pozwalający różnym obiektom reagować różnie na tę samą wiadomość.
Proces implementacji:
Dzięki zdefiniowaniu interfejsu TranslationStrategy i wprowadzeniu programowania zorientowanego na interfejs, zyskaliśmy następujące korzyści:
TranslationService może używać różnych strategii tłumaczeń przy każdym wywołaniu.TranslationService.TranslationService sprawia, że usługa staje się bardziej bezstanowa i bezpieczniejsza wątkowo.Optymalizacja struktur instrukcji warunkowych to ważny środek poprawy jakości kodu. Trzy metody przedstawione w tym artykule — programowanie defensywne, metoda tablicy przeszukiwania oraz programowanie zorientowane na interfejs (połączone z polimorfizmem) — każda ma swoje odpowiednie scenariusze:
W rzeczywistym rozwoju często musimy wybierać odpowiednie metody w oparciu o konkretne sytuacje, a czasem nawet musimy kompleksowo stosować wiele technik. Ważne jest, aby zachować równowagę między prostotą, czytelnością i utrzymywalnością kodu, wybierając rozwiązanie, które najlepiej pasuje do aktualnego problemu.
Pamiętaj, że nadmierna optymalizacja może prowadzić do nadmiernie złożonego kodu. Utrzymywanie kodu prostym i czytelnym jest zawsze główną zasadą. Podczas stosowania tych technik należy podejmować mądre decyzje w oparciu o konkretne potrzeby projektu i poziom techniczny zespołu.