Codziennością każdego programisty jest praca z kodem źródłowym. Ważne, aby zadbać o czysty kod. Dlaczego? Odpowiedź na to pytanie znajduje się w tym artykule.

Kod źródłowy jest zapisem woli programisty, która ma być zrealizowana przez procesor. W przypadku języków imperatywnych będzie to lista czynności do wykonania, a w przeciwieństwie do języków deklaratywnych jest to zbiór warunków jakie rozwiązanie ma spełniać1.

Procesor nie czyta kodu źródłowego. Procesor otrzymuje polecenia na podstawie przetworzonego kodu źródłowego najczęściej w formie kodu maszynowego lub kodu pośredniego (bytecode). Programem, który czyta Twój kod źródłowy jest analizator składniowy (parser). Jednak parser jest bezwzględny – bezpardonowo wytnie misternie przygotowane wcięcia, literackie nazwy funkcji oraz komentarze pisane wierszem z kodu i wyciśnie to co jest dla niego ważne – tokeny służące dalszej analizie.

W przypadku długoterminowych projektów kod źródłowy jest częściej czytani niż pisany. Czytanie kodu następuje w sytuacji rozszerzania funkcjonalności oraz naprawy potencjalnych błędów. Zatem kto potrzebuje kod źródłowy? Są to dwie grupy:

  • Ty sam,
  • Twoi koledzy z zespołu.

Za każdym razem osoba analizująca kod musi zrozumieć i poprawnie zinterpretować działanie kodu oraz przewidzieć sekwencję realizowanych instrukcji (code execution path). Nie są odosobnione przypadki trudności w interpretacji i analizie danego fragmentu kodu przez jego autora już po upływie kilku tygodni2.

Zatem odpowiemy na pytanie jak osiągnąć czysty kod – jak należy kodować, aby kod był czytelny, zrozumiały oraz łatwy do pracy nad nim?

czysty kod
Praca z czystym kodem jest łatwiejsza i przyjemniejsza.

Jak mieć czysty kod?

Wraz z rozwojem dziedziny inżynierii oprogramowania społeczność programistów opracowała szereg zasad oraz dobrych praktyk dotyczących wytwarzania oprogramowania. Przytoczmy kilka z nich.

Formatowanie kodu

W poprzednim artykule zostało przedstawione dlaczego formatowanie kodu jest ważne oraz dlaczego automatyczne formatowanie kodu jest jeszcze ważniejsze. Podsumowując: automatyczne formatowanie kodu poprawia jego czytelność i spójność oraz zmniejsza koszt jego rozwoju.

Keep It Simple Stupid

Reguła wskazuje, że proponowane rozwiązania powinny być możliwie proste i łatwe w zrozumieniu.

Don’t Repeat Yourself

Reguła określona jest w dwojaki sposób. W odniesieniu do kodu zaleca, aby powtarzające się fragmenty kodu wydzielić do funkcji. W drugim przypadku wskazuje, iż powtarzające się czynności programisty powinny być zautomatyzowane na przykład w postaci skryptów i narzędzi automatyzujących. Prostym przykładem są narzędzia formatujące kod źródłowy.

SOLID

Zbiór zasad, które zaproponował Robert C. Martin. Zasady określają w jaki sposób powinien być zorganizowany kod pisany w duchu paradygmatu programowania obiektowego. Są to następujące zasady:

  • każda klasa powinna posiadać tylko jedną odpowiedzialność,
  • każdy element systemu powinien być otwarty na rozszerzenia, ale zamknięty na modyfikacje,
  • funkcje używające adresów3 do obiektów typów bazowych muszą być w stanie również używać wskazań do obiektów typów dziedziczących,
  • podział ogólnych na wiele wyspecjalizowanych interfejsów,
  • zależność pomiędzy modułami wysokopoziomowymi, a niskopoziomowymi powinna być realizowana poprzez abstrakcje.

Prawo Demeter

W skrócie prawo Demeter określa, że w metodzie można odwoływać się bezpośrednio jedynie do metod obiektów wykorzystywanych w tej metodzie. Celem tego prawa jest ograniczenie zależności. Drugą, mniej oczywistą zaletą tego podejścia jest ułatwienie procesu debuggowania kodu. Dla zobrazowania posłużmy się dwoma fragmentami kodu:

object.call_a().call_b().call_c()
result_a = object.call_a()
result_b = result_a.call_b()
result_b.call_c()

W przypadku wykonywania kodu w trybie krokowym (stepping) w pierwszym przypadku aby wejść do wnętrza metody call_c() należy w pierwszej kolejności wejść do wnętrza metody call_a() a następnie do metody call_b() oraz z tych metod wyjść. W drugim przypadku metoda call_c() jest bezpośrednio dostępna4.

Komentarze

Komentarze w niektórych środowiskach są tematem kontrowersyjnym. Niektórzy uważają, iż komentowanie kodu świadczy o tym, że kod nie jest wystarczająco KISS. Niektórzy podnoszą, że komentarze, na skutek zmian w kodzie, szybko stają się nieaktualne, a przez to mylące. Jest w tym dużo racji, niemniej lepiej mieć komentarz niż go nie mieć5 (pomijając ekstremalne przypadki, gdy linijek komentarza jest więcej niż właściwego kodu), bo nawet przestarzały komentarz świadczy o zmianach w działaniu kodu (taką informację również można wywnioskować poprzez analizę historii zmian w repozytorium). Komentarze nie powinny streszczać działania kodu, a opisywać realizowaną logikę biznesową w uogólniony sposób.

Jest tutaj jeden istotny wyjątek – testy jednostkowe. W tym przypadku komentarz opisujący test powinien zawierać opis scenariusza testowego wraz z przyjętymi założeniami oraz oczekiwanymi rezultatami (czyli niejako powtórzenie tego, co jest zawarte w kodzie testu). Sam test jednostkowy może ulec zmianie, jednak scenariusz testowy powinien być niezmienny, a zapisany komentarz wskazuje co dany test powinien weryfikować. Drugim ważnym do komentowania miejscem są przypadki brzegowe (najczęściej instrukcje warunkowe wyjścia z pętli lub funkcji). Taki komentarz powinien wprost odwoływać się do logiki biznesowej i wyjaśniać, dlaczego sekwencja kodu kończy swoje działanie.

PEP-20

Propozycja ulepszeń języka Python zawiera pythonic way oraz rekomendacje jak pisać dobry i czysty kod. Zasady w głównej mierze wskazują, że kod powinien być pisany dla ludzi, a nie dla maszyn.

Lektura obowiązkowa

Większość z przytoczonych powyżej zasad i dobrych praktyk poruszanych jest również w książce wspomnianego wcześniej autora Roberta C. Martina. Książka Czysty kod. Podręcznik dobrego programisty jest lekturą obowiązkową dla programistów, którzy chcą, aby życie było łatwiejsze a ich kod źródłowy doceniony.

Twój zespół potrzebuje wsparcia we wdrożeniu dobrych praktyk lub potrzebujesz zespół, który posprząta Twój kod?

  1. więcej o paradygmatach programowania można znaleźć tutaj ↩︎
  2. również osobiste doświadczenie autora wpisu ↩︎
  3. w szczególności wskaźników lub referencji ↩︎
  4. można również ustawić pułapkę (breakpoint) wewnątrz pożądanej metody, ale to jest dodatkowy wysiłek, który trzeba ponieść ↩︎
  5. niektórzy wskazują, że nieaktualny kod powoduje zamęt i dodatkowy koszt, więc lepiej takiego nie mieć ↩︎


Leave a Reply

Your email address will not be published. Required fields are marked *