Czysty kod to taki, który jest łatwy do odczytywania, zrozumienia i modyfikowania. To kod minimalny i zwięzły, o ile te atrybuty nie wpływają na czytelność. Tworzenie czystego kodu jest sztuką. Programiści wypracowali wiele zasad, których przestrzeganie może pomóc w tworzeniu czystszego kodu.

(...)Być może się zastanawiasz nad różnicą między kodem czystym i prostym. Te dwie koncepcje są blisko ze sobą związane, ponieważ czysty kod ma tendencję do bycia prostym, a prosty kod zwykle jest czysty. Mimo to istnieje możliwość spotkania się ze złożonym kodem, który wciąż jest czysty. Prostota koncentruje się na unikaniu złożoności. Czysty kod idzie o krok dalej i koncentruje się również na zarządzaniu nieuniknioną złożonością, np. przez efektywne używanie poleceń i standardów.

 

Dlaczego należy tworzyć czysty kod?

 

(...) Czysty kod jest łatwiejszy do zrozumienia zarówno dla Ciebie w przyszłości, jak i dla innych programistów pracujących z tym kodem, ponieważ będą mieli tendencję do dodawania czystego kodu, a tym samym wzrośnie możliwość jego tworzenia razem z innymi programistami. W efekcie czysty kod może znacznie zmniejszyć koszt projektu. Robert C. Martin w swojej książce Czysty kod. Podręcznik dobrego programisty (Helion, 2010) wyjaśnił, że programiści spędzają większość czasu na czytaniu starego kodu w celu tworzenia nowego. Jeżeli stary kod jest łatwy do odczytania, to ten proces będzie znacznie szybszy.

 

Stosunek czasu poświęconego na odczytywanie kodu do czasu poświęconego na jego tworzenie wynosi ponad 10 do 1. Nieustannie odczytujemy stary kod, aby utworzyć nowy. Dlatego łatwiejszy odczyt istniejącego kodu ułatwia tworzenie nowego.

 

Jeżeli potraktujemy ten stosunek dosłownie, to można go zwizualizować jak pokazałem na rysunku. Na osi X mamy liczbę wierszy kodu utworzonych w danym projekcie oprogramowania. Z kolei Y przedstawia czas potrzebny na utworzenie każdego dodatkowego wiersza kodu. Ogólnie rzecz biorąc, im większa ilość kodu już istniejącego w projekcie, tym więcej czasu potrzeba na utworzenie każdego dodatkowego wiersza. To dotyczy kodu zarówno czystego, jak i brudnego.

 

 

Załóżmy, że utworzono n wierszy kodu i ma być dodany kolejny wiersz. Ten nowy wiersz potencjalnie może wpływać na wszystkie wcześniej utworzone. Na przykład jego dodanie może mieć negatywny wpływ na wydajność działania całego projektu. Może używać zmiennej, która została zdefiniowana gdzieś indziej. Może zawierać błąd (prawdopodobieństwo tego wynosi c), którego znalezienie będzie wymagało przejrzenia całego projektu. To oznacza, że oczekiwany czas — a tym samym i koszt — dodania wiersza kodu wynosi c·T(n) dla stale zwiększającego się czasu funkcji T razem ze zwiększającymi się danymi wejściowymi n. Dodanie wiersza kodu może wymagać dodania kolejnych wierszy w celu zapewnienia wstecznej zgodności.

 

Dłuższy kod może wiązać się z wieloma innymi komplikacjami, ale już wiesz, o co w tym chodzi: im więcej tworzysz kodu, tym więcej masz dodatkowej złożoności, która będzie Cię spowalniać.

 

Na rysunku możesz również zobaczyć różnicę między tworzeniem kodu brudnego i czystego. Na krótką metę oraz w małych projektach utworzenie brudnego kodu wymaga mniej czasu — jeżeli tworzenie brudnego kodu nie przynosiłoby żadnych korzyści, nikt by go nie tworzył! Jeśli całą funkcjonalność możesz upchnąć w 100-wierszowym skrypcie, nie musisz inwestować wiele czasu i zastanawiać się nad restrukturyzacją projektu. Problemy pojawiają się, gdy zamierzasz dodać więcej kodu. Kiedy monolityczny plik kodu powiększa się ze 100 do 1000 wierszy, wówczas staje się mniej efektywny niż znacznie bardziej przemyślany kod, którego struktura została logicznie umieszczona w różnych modułach, klasach lub plikach.

 

Oto praktyczna zasada: zawsze twórz kod czysty i przemyślany. Dodatkowy koszt związany z przemyśleniem, refaktoryzacją i restrukturyzacją kodu zwróci się wielokrotnie w przypadku każdego nieco bardziej złożonego projektu. Czasami stawka może być bardzo wysoka: w 1962 roku NASA próbowała wysłać statek kosmiczny na Wenus, ale drobny błąd — pominięcie łącznika w kodzie źródłowym — spowodował, że inżynierowie wydali polecenie samozniszczenia. Skutkiem była utrata rakiety, która w owym czasie kosztowała 18 milionów dolarów. Jeżeli kod byłby czysty, inżynierowie być może wychwyciliby ten błąd.

 

Nawet jeśli nie jesteś inżynierem zajmującym się technologią kosmiczną, podejście polegające na starannym tworzeniu kodu źródłowego okaże się pomocne. Prosty kod pomaga również w skalowaniu projektu dla wielu programistów i większej liczby funkcjonalności, ponieważ mniej programistów będzie przerażonych poziomem złożoności projektu.

 

Zatem przechodzimy do tematu tworzenia czystego i prostego kodu.

 

Tworzenie czystego kodu - zasady

 

Tworzenia czystego kodu nauczyłem się na własnej skórze podczas pracy nad rozproszonym systemem przetwarzania grafiki, który był częścią moich badań doktorskich. Jeżeli masz jakiekolwiek doświadczenie z tworzeniem aplikacji rozproszonych — gdy dwa procesy działające w oddzielnych komputerach współpracują ze sobą za pomocą komunikatów — to doskonale wiesz, że związana z tym złożoność może bardzo szybko stać się przytłaczająca. Mój kod osiągnął wielkość liczoną w tysiącach wierszy i błędy zaczęły się pojawiać dość regularnie. Przez tygodnie nie poczyniłem żadnego postępu i to było naprawdę frustrujące. 

 

W teorii koncepcje brzmiały obiecująco, ale z jakiegoś powodu nie sprawdzały się w mojej implementacji.

 

Wreszcie po mniej więcej miesiącu wytężonej i bezowocnej pracy nad bazą kodu zdecydowałem się na jej znaczne uproszczenie. Jedna ze zmian polegała na tym, że zacząłem korzystać z bibliotek zamiast samodzielnie opracowywać funkcjonalności. Usunąłem bloki kodu umieszczone w komentarzach, pozostawione do ewentualnego użycia w przyszłości. Zmieniłem nazwy zmiennych i funkcji. Przeprowadziłem restrukturyzację kodu na postać logicznych jednostek i zdefiniowałem nowe klasy zamiast upychać wszystko w jednej klasie „boga”. Po jakimś tygodniu mój kod stał się nie tylko czytelniejszy i zrozumiały dla innych, ale również znacznie efektywniejszy i zawierał mniej błędów. Frustracja zmieniła się w entuzjazm — czysty kod uratował mój projekt!

 

Poprawienie bazy kodu i zmniejszenie złożoności nosi nazwę refaktoryzacji. Jeżeli chcesz otrzymać czysty i prosty kod, refaktoryzacja powinna być regularnym i istotnym elementem procesu tworzenia oprogramowania. Tworzenie czystego kodu właściwie sprowadza się do dwóch kwestii: poznanie najlepszych sposobów na opracowanie kodu zupełnie od zera oraz umiejętność wracania do utworzonego wcześniej kodu i jego analizowania. Wybrane spośród najważniejszych technik pomocnych w tworzeniu czystego kodu przedstawię w zamieszczonych tutaj 17 zasadach. Wprawdzie każda z nich dotyczy unikatowej strategii tworzenia czystszego kodu i część się nakłada, ale jestem pewny, że połączenie nakładających się zasad prowadzi do zmniejszenia przejrzystości i ogranicza pole manewru. 

 

1. Spójrz z szerszej perspektywy - zdecyduj, które funkcjonalności są potrzebne w pierwszej kolejności.

2. Stań na ramionach olbrzymów - korzystaj z dostępnych bibliotek.

3. Twórz kod dla ludzi, nie dla urządzeń.

4. Używaj odpowiednich nazw.

5. Zachowaj spójność i zgodność ze standardami.

6. Używaj komentarzy.

7. Unikaj niepotrzebnych komentarzy.

8. Zasada najmniejszego zaskoczenia - komponent systemu powinien zachowywać się w sposób oczekiwany przez większość użytkowników.

9. Nie powtarzaj się.

10. Zasada pojedynczego celu - każda funkcja powinna wykonywać tylko jedno podstawowe zadanie.

11. Testuj kod.

12. Małe jest piękne - mały kod często wymaga względnie niewielkiej liczby wierszy do wykonania pojedynczego zadania.

13. Prawo Demeter - celem prawa Demeter jest zachowanie luźnego połączenia między obiektami i operacjami, aby można było wprowadzać modyfikacje w którejkolwiek części bez powodowania poważnego wpływu na tę drugą.

14. Nie potrzebujesz tego - kod twórz tylko wtedy, gdy masz 100% pewności, że jest niezbędny.

15. Nie używaj zbyt wielu poziomów wcięć.

16. Używaj wskaźników.

17. Zasada harcerza i refaktoryzacja - pozostaw po sobie porządek większy, niż zastałeś.

 

Fragment pochodzi z książki The Art of Clean Code. Jak eliminować złożoność i pisać czysty kod, (Christian Mayer - wyd. Helion 2023).