
Czas czytania: 9 min
Jeśli dobrze liczę to za kilka miesięcy minie mi 10 lat od kiedy komercyjnie programuję. To sporo czasu!
Widziałem trochę kodu i sam niemało wyprodukowałem. Czasami wydaje mi się, że widziałem już wszystko, chociaż na pewno zdajesz sobie sprawę, że regularnie jestem zaskakiwany! Pamiętam czasy, gdy zaczynałem swoją przygodę z programowaniem “na poważnie”. Byłem przekonany, że jakość kodu zależy głównie od użycia zaawansowanych możliwości języka czy użycia wzorców projektowych tam, gdzie jest to możliwe. Patrzyłem zafascynowany na kod, w którym zawiłość rozwiązania była ledwo zrozumiała nawet dla autorów. Robiło to na mnie spore wrażenie. Też chciałem pisać tak skomplikowany kod!
Dosyć szybko trafiłem do firmy, gdzie kod wyglądał inaczej. Pomimo że wciąż miałem niewiele doświadczenia, w większości byłem w stanie go samodzielnie zrozumieć! O co tutaj chodzi? Czy Ci ludzie nie znają wzorców projektowych albo nie potrafią napisać czegoś generycznie? W kilku miejscach natrafiłem na “porządny kod”, pełen chytrych skrótów, gdzie trzeba było posiedzieć i porządnie pogłówkować. Oczywiście właśnie taki kod chciałem pisać!
Na szczęście natrafiłem na wspaniałych programistów, którzy szybko wyjaśnili mi, o co chodzi z tym ich prostym kodem… Zanim Ci opowiem, czego się dowiedziałem, to przedstawię Ci moją wersję historii programowania.
Pasy zapięte? Jedziemy!
Dlaczego pisać prosty kod?
Dawno, dawno temu, za siedmioma górami… programiści tworzyli swój kod za pomocą zer i jedynek. Za jakiś czas pojawiły się języki niskiego (czy bardzo niskiego) poziomu, a więc asemblery. Nie wiem, czy wpadł Ci kiedyś, jakiś w ręce, ale w pracy z nimi trzeba być mocno skupionym. Nawet w przypadku prostych obliczeń. Powtarzam – obliczeń! Nie skomplikowanej logiki biznesowej.
Programiści słusznie stwierdzili, że nie jest to ani proste, ani zrozumiałe, ani specjalnie intuicyjne. Postanowili stworzyć języki, które stały się bardziej zrozumiałe dla ludzi, które potem były zamieniane “automagicznie” w kod zrozumiały dla procesora. Następnie je udoskonalali i dotarliśmy do języków wysokiego poziomu oraz do generatorów kodu z języka “ludzkiego” (patrz GPT-3).
Oto krótka historia programowania! Ode mnie – dla Ciebie! Nie dziękuj!😉
Jak myślisz? Po co to robili? Na początku wszystko było ekstremalnie zawiłe i ledwo zrozumiałe! A więc to, co wyróżnia kod ludzi z doświadczeniem według mojej młodzieńczej definicji… Byli to jednak mądrzy ludzie, a więc jakiś powód musiał być.
Śmiem twierdzić, że w głównej mierze była to prostota. Z jednej strony kod miało się łatwiej pisać, ale z drugiej (być może ważniejsze) – innej osobie miało być prościej go zrozumieć!
Oczywiście potem powstawały zaawansowane koncepcje programistyczne. Pomimo, że czasami trudne do zrozumienia, powstawały w tym samym celu. A tym celem była prostota.
Nie czyń drugiemu co Tobie niemiłe…
Już się domyślasz, jaką tajemnicę zdradzili mi poznani w nowej firmie programiści na początku mojej drogi? W kodzie, w którym pisali ważna była prostota. Programowanie to praca zespołowa i nigdy nie wiadomo, kiedy wyląduje się w “nieswoim kodzie”.
Tutaj mała dygresja. Bardzo nie lubię koncepcji “przynależności kodu do programisty” w zespole czy firmie. Kod, jeżeli już kogoś musi być – to wszystkich! Może kiedyś napiszę na ten temat więcej, ale póki co wracamy do głównego wątku.
Twórz prosty kod, bo jestem przekonany, że pragniesz taki zastać. Nieutrzymywalny koszmar i bełkot nie jest tym, co chcesz ujrzeć, gdy dostajesz do poprawienia drobny błąd. Użycie każdej zaawansowanej metody programowania, jaka jest Ci znana, w większości przypadków doprowadzi do kodu, który jest:
- zawiły, przez co bardziej zamknięty na zmiany,
- trudny w utrzymaniu,
- wolniejszy (tak! te wodotryski nie są za darmo!)
- bardziej podatny na ukryty błąd,
- a ostatecznie, tak naprawdę do przepisania.
Na doświadczonych programistach nie robisz wrażenia zawiłym kodem, pełnym zaawansowanych funkcji językowych i innych “usprawnień”. Przede wszystkim dlatego, że większość programistów, bez względu na doświadczenie, je zna. Co ciekawe, Ci z mniejszym używają ich częściej, bo są “zaawansowane”, a więc trzeba ich używać.
Każdy głupek może napisać kod, który jest zrozumiały dla komputera. Dobrzy programiści piszą kod, który jest zrozumiały dla ludzi.
Kent Beck
Tutaj nasuwa mi się metafora pasa z narzędziami. Dobrze jest w nim mieć wiele narzędzi do odpowiednich zadań. Bardzo ważne jest to, abyś wiedział do czego każde z nich służy. A jeszcze ważniejsze – do czego nie służy!
Komunikacja
Na tym blogu nie po raz pierwszy wspominam, że to jedna z najważniejszych umiejętności jakie musisz posiąść, jeżeli chcesz być dobry w tym fachu.

Ostatnio czytałem wspaniałą książkę Pana Dale Carnidge “Jak zdobyć przyjaciół i zjednać sobie ludzi”, gdzie autor wręcz obnaża wszelki błędy, jakie większość ludzi (nie tylko programistów) popełnia podczas komunikacji. Warto zagłębić się w tę lekturę! Polecam!
Ok, ale co z tą komunikacją? Pisanie kodu to też komunikacja!
Z jednej strony z komputerem. Zmuszamy te chłodne i nieczułe maszyny, aby zrobiły to co chcemy. I każdy kto napisał chociaż linijkę kodu wie, że komputery właśnie takie są (chłodne i nieczułe), bo nigdy nie chcą współpracować od razu!
Z drugiej strony, i to jest zdecydowanie ważniejsze, kod ma służyć komunikacji z innymi programistami. Nie jesteśmy samotną wyspą, a programowanie to gra zespołowa. Oczywiście czasami zdarza się jakiś występ solowy, ale nie jest to bynajmniej regułą.
Komunikacja musi być przede wszystkim prosta! Ja wiem, że w naszym fachu uwielbiamy trudne słowa, TLS’y (trzy literowe skróty) i angielskie wtrącenia. Niektórzy posługiwanie się nimi wynieśli do poziomu sztuki! Nie jestem purystą i sam ich czasem używam. Bywa, że tak jest bardziej precyzyjnie. Każdorozawo warto się jednak upewnić, że wszyscy się rozumiemy! Nadrzędną wartością powinno być dostarczanie dobrych jakościowo projektów na czas. Zespołowo. Bez dobrej, a więc prostej komunikacji wydaje się to mało realne.
I jakie mamy z tego wnioski? Tak! Kod też musi być prosty, jednak…
Prosty kod jest dużo trudniej napisać
Prostota kodu jest tym co odróżnia amatorów od profesjonalistów! Zabrzmiało srogo i górnolotnie, ale tak miało to zabrzmieć! Cytując klasyka:
Może i ten sweter jest wieśniacki, ale taki właśnie ma być…
Grucha “Chłopaki nie płaczą”
Gdyby to było takie oczywiste to pracowalibyśmy tylko z takim prostym kodem, a zarówno ja, jak i Ty doskonale wiemy, że tak nie jest!
Aby napisać dobry, prosty kod potrzebna jest szersza perspektywa. To z kolei wymaga zrozumienie całego systemu. Czy widzisz już plusy? Chcąc napisać banalny kod – musisz rozumieć system szerzej niż Twoja funkcjonalność!
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
Kernighan’s law
Mam wrażenie, że skomplikowanie kodu często nie wynika ze złej woli czy braku umiejętności. Często jest to “dmuchanie na zimne”. Staramy się być zbyt przewidujący! Zapominamy o jednej z podstawowych zasad programowania (że też nie uczą jej na studiach)! Chodzi mi o YAGNI (You Ain’t Gonna Need It).
Często skomplikowanie kodu wynika z przygotowania go do nigdy nie następujących zastosowań. Co więcej, z mojego doświadczenia wynika, że nawet jeżeli te zastosowania się jednak wydarzą (rzadko, ale jednak) – to i tak ten kod wymaga przystosowania. Aż tak przewidujący jest mało kto!
Zasada YAGNI jest prosta i warto z niej korzystać. Jeżeli kod nie musi czegoś robić, to nie implementujmy tego na zapas. Zazwyczaj kończy się to skomplikowanym kodem, który nie obsługuje tych przypadków, na jaki go przygotowaliśmy! A te, do których go przygotowaliśmy są “zabetonowane” swoją zawiłością.
Słyszałem, że chcesz być seniorem?
Gdzieś, kiedyś widziałem takie zestawienie. Sparafrazuje to, bo dokładnie nie pamiętam i nie byłem w stanie odszukać, skąd to znam:
- Junior – przed napisaniem kodu stara się zrozumieć, jak ma działać jego funkcjonalność,
- Mid – przed napisaniem kodu zastanawia się, jak funkcjonalność, którą zaimplementuje, wpłynie na moduł w skład, którego wchodzi,
- Senior – widzi większość zależności i wie doskonale czy rzeczywiście musi coś pisać czy może wykorzystać już gotowe rozwiązanie.
Podoba mi się ten podział i się z nim zgadzam. To zrozumienie systemu (albo przynajmniej prędkość, z jaką pojmujemy nowo poznany system) definiuje nasze doświadczenie. Chcesz być seniorem? Zrozum system, w którym pracujesz, a zaowocuje to prostym kodem!
Znowu dygresja. Nie lubię tych poziomów seniority, ale o tym (być może) napiszę przy innej okazji. Tutaj zostawię Cię z jedną myślą – czy będąc juniorem jesteś zwolniony/-a z pisania dobrego kodu i rozumienia systemu, w którym pracujesz?
Zaplanuj prosty kod
No dobra, ale jak pisać ten prosty kod?
The sooner you start to code, the longer the program will take.
Roy Carlson, University of Wisconsin
Zakładam, że już teraz jest to Twój nawyk, a więc tylko przypominam. Zanim coś napiszesz – pomyśl. Może coś narysuj? Może to być diagram UML, ale i prosty schemat blokowy “zrobi robotę”. Diagramy (a więc graficzne przedstawienie problemu) jest dużo lepsze od słownego zapisu, ponieważ tak działa ludzki mózg. Ewolucyjnie jest przystosowany głownie do odnajdywania wzorców – szczególnie z bodźców wizualnych. Dobry rysunek jest warty setki słów!

Jeżeli mi nie wierzysz to uwierz Uniwersytetowi w Minnesocie. Przeprowadzono tam badania, gdzie dowiedziono, że prezentacje zawierające “dobre” grafiki były o 43% bardziej przekonywujące i zrozumiałe niż te czysto tekstowe. Co więcej – prezenterzy byli oceniani na bardziej profesjonalnych!
Z takim podejściem wiążą się, więc co najmniej trzy plusy:
- na etapie planowania zauważysz kilka błędów w rozumowaniu (a błędy w planowaniu najłatwiej i najtaniej usunąć),
- jesteś postrzegany w firmie czy zespole bardzij profesjonalnie,
- mimochodem powstanie “delikatna dokumentacja”.
Użyjmy teraz zdrowego rozsądku i postawmy tezę. Jeżeli jesteś w stanie stworzyć prosty diagram – to jesteś z w stanie stworzyć z tego prosty kod. Ma to sens?
Jeżeli już na etapie planowania diagram wymyka się spod kontroli oznacza to zapewne, że:
- nie rozumiesz szerszej perspektywy,
- diagram jest zbyt ogólny i należy wejść głębiej z abstrakcją
Na diagramie z pewnością dużo szybciej zauważysz, gdzie istnieje szansa na komplikację kodu. Używaj ich! Wystarczą proste diagramy blokowe!
Lepiej zaczynać od razu czysto
Nie raz słyszałem, że “gdybym miał więcej czasu to napisałbym/-łabym to lepiej”. W większości przypadków to nieprawda. Skąd to wiem? Łatwo to obnażyć zadając pytanie: “A co konkretnie byś zrobił/-a, aby było lepiej?” W większości odpowiedzi są niesatysfakcjonujące. Nawet jak odpowiedź jest dobra, to dlaczego taki kod nie powstał od razu? Pewnie był niezaplanowany.
Dobry kod można z powodzeniem pisać od początku. Wbrew pozorom jest szybciej! Dobry, prosty kod jest łatwo rozwijalny. Prostszy w zrozumieniu. Również dla Ciebie! Czy to w oczywisty sposób nie sprawia, że będzie szybciej?
Rozbijaj problemy
Prosty kod trudniej napisać! Ale można to sobie ułatwić. Z pomocą idzie pierwsza z zasad SOLID (S – Single responsibility principle).
Każda klasa ma tylko jedną odpowiedzialność. Ja uważam, że każda metoda ma jedną odpowiedzialność. Rozbijając kod łatwiej dostrzeżesz czy go nie duplikujesz. Praktycznie bez problemu rozplątujesz najbardziej zawiłe metody. Nie będę wchodził w dalsze szczegóły, bo to na pewno dla wszystkich sprawa oczywista. Napisałem o tym, bo lubimy o tym fundamencie zapominać!
Nazewnictwo jest ważniejsze niż myślisz
To klucz prostoty!
Ktoś mi kiedyś powiedział (zabij mnie, ale nie wiem kto), że w programowaniu są tylko dwie trudne rzeczy: obsługa błędów i nazewnictwo. Nie mogę się bardziej zgodzić!
Są to trudne zagadnienia, ale kluczowe w dobrym kodzie. Skupmy się tym razem tylko na tym drugim!
W kodzie, w którym wszystko nazywa się tak, że na pierwszy rzut oka, wiesz czym jest – można zrobić dosłownie wszystko. Zbędne są nawet komentarze! Czy prosto jest się tego nauczyć? Oczywiście, że nie! Obawiam się nawet, że trzeba się tego uczyć całe życie!
Tak czy owak – warto! Nazwy to pierwsza rzecz jaką widzisz odwiedzając klasę, metodę czy próbując zrozumieć parametr. Dobra nazwa jest krytyczna! Może często zaoszczędzić sporo myślenia czy nawet debugowania przyszłym programistom pracującym nad kodem.
Argument ostateczny – jak myślisz, co się dzieje z niezrozumiałym kodem
Zastanawiałeś się kiedyś co się stanie z Twoim kodem, którego nikt nie potrafi zrozumieć… albo zrozumienie go zajmuje zdecydowanie za dużo czasu?
Trudno było napisać – to teraz trudno zrozumieć
Autor nieznany (i to nawet lepiej)
Tak – dobrze myślisz – zostanie usunięty i zastąpiony innym.

Jak rozumiesz funkcjonalność, a kodu nie, to go wykasuj! To prosta i dobra zasada. Ot tak. Po prostu. Nie staraj się przerabiać kodu, którego nie możesz pojąć w skończonym czasie. Jeżeli wiesz jak funkcjonalność działa to wiesz wszystko, aby wytworzyć nowy, prostszy kod. Być może w skład funkcjonalności muszą wejść skomplikowane obliczenia – skomentuj je. Ja wiem, że dobrze napisany kod sam się dokumentuje. Postaw się jednak w sytuacji innego programisty – czasami dwa zdania pomogą mu zrozumieć Twój zamysł zdecydowanie szybciej, a Twój kod ma szansę przetrwać!
One of my most productive days was throwing away 1000 lines of code.
Ken Thompson, early developer of UNIX OS
Wyjątek
Oczywiście są tematy optymalizacji, które wymagają czasami bardzo skomplikowanych (ale ekstremalnie szybkich) operacji, które na pierwszy rzut oka wyglądają bardziej na koronkę koniakowską niż kod…
Co wtedy robić? Ten fragment kodu odizoluj od reszty… i pozostaw stosowny komentarz czy (nawet lepiej) dobrze nazwij funkcję. Tym razem to właśnie “takie ma być” (znowu jak sweter Gruchy), bo jest szybciej i ma diametralne znaczenie.
Podsumowanie
Dobra – uderzam prosto z mostu – być może pisanie prostego kodu to najważniejsza umiejętność techniczna każdego programisty. Jest to również najważniejsza cecha, która odróżnia amatora od profesjonalisty (czy tam seniora od innych – jak zwał tak zwał).
Czy mnie, aby nie ponosi? Nie wydaje mi się!
Najbardziej wartościowi programiści potrafią spojrzeć szeroko na cały system i miejsce swojego kodu w nim. Tylko niedoświadczeni koderzy skupiają się wyłącznie na tym, aby ich kod spełniał powierzone mu zadanie. Dodatkowo potrzeba doświadczenia i mądrości (uuu mocne słowo!), aby zrozumieć, że jeżeli kod działa to już jest nieźle. Samo działanie to dopiero początek, ale o tym było sporo w treści artykułu.
I żeby podbić ostatecznie pompatyczność tego podsumowania, proponuję wprowadzenie do swojego programistycznego serca takiej dewizy:
“Zrozumiały dla innych programistów kod powinien być celem nadrzędnym w każdej organizacji i w każdym kodzie.”
Słyszałem, że chcesz być seniorem… a może leadem właśnie… super! Zacznij od pisania prostego kodu! Jasność przekazywania myśli jest umiejętnością, która Ci pomoże w Twojej karierze. Jako senior musisz myśleć o tym, jak Twój kod wpływa na całość rozwiązania – łączenie z jego późniejszym utrzymaniem!
Pisz prosty kod! Tylko tyle i aż tyle… A na koniec mała przestroga:
Zawsze pisz taki kod, jakby koleś, który miał go czytać i serwisować, był brutalnym psychopatą, który wie, gdzie mieszkasz.
Dave Carhart
A Ty jaki kod piszesz? Jestem bardzo ciekawy Twojego zdania na ten temat. Napisz komentarz poniżej lub napisz do mnie! Temat jest mi bardzo bliski i z przyjemnością o nim podyskutuje.
Jeżeli Ci się spodobało i chcesz być na bieżąco – zapisz się na newsletter, pobierając dokument poniżej!