Kod nigdy nie kłamie, komentarze czasami

Kod nigdy nie kłamie, komentarze czasami. Jednak dobre komentarze także istnieją.

Zapytaj swojego kolegę, programistę czy komentarze w kodzie to dobry pomysł. Jak myślisz, jaka zazwyczaj pojawia się odpowiedź?

  • Absolutnie!
  • Nie.
  • Chyba Cię po(..)

Bez zastanowienia komentujemy także komentarze podczas Code Review – zostawiając pozostawione emocji, krótkie i bez krzty wyjaśnienia wrzutki: „usuń ten pieprzony komentarz!”. 💥

Mam wrażenie, że sporo zmieniło się po szaleńczym hajpie na książkę „Clean CodeUncle Boba (zresztą świetną, którą wpisałbym w obowiązkowy kanon lektur programisty). To w niej znajdziemy rozprawkę na kilkanaście stron odnośnie komentarzy – (nie)stety stawiając je w obliczu zła najgorszego – patrząc na ilość warunków, które wpływają na ich negatywny odbiór.

„Zapamiętujemy czego robić nie można, zapominając o tym, co robić MOŻNA lub WYPADA.”

Coś tu cuchnie…

Wracając jednak do tytułowego cytatu. Tak – komentarze mogą kłamać, bo modyfikując logikę biznesową, często pod presją czasu zapominamy o tym co otacza nasz najważniejszy kod. Mając oddech Project Managera na plecach, zależy nam na wykazaniu się i dostarczeniu zmiany jak najszybciej.

Zmiana została wprowadzona – mamy mały „sukces”… I porażkę zarazem.

Niestety ale komentarz opiewający zmodyfikowany fragment kodu, nie odpowiada aktualnej implementacji. Gorzej, może nie wpływać na rezultat kompilacji, wynik uruchomionych testów czy narzędzi SCA. Przecież działa. Wprowadziliśmy zmianę, degradując przy tym kod.

Jednak nasze obyczaje zaczęły sięgać także drugiego dna. Można powiedzieć, że przyjęliśmy zasadę:

„Kto komentuje, ten smród w kodzie snuje. 💩”

Nadużywanie komentarzy jest złe. Tutaj się zgadzamy. Jest wiele momentów gdy komentarz jest zbędny. Natomiast nie wykorzystywanie jego potencjału – także może nie być najlepszym pomysłem.

Istnieją tylko dwa rodzaje komentarzy

Dzielę komentarze pojawiające się w kodzie na dwa typy – tak czysto zero-jedynkowo. Nie ze względu na zastosowanie, ale ze względu na wartość jaką niosą swoją treścią.

Nie wnoszące wartości ⛔️

To te, które wprowadzają szum. Zbędny balast, bez którego kod będzie bardziej czytelny. To tych przykładów możemy wygenerować najwięcej. Tłumacząc podtytuł, nie wnoszące wartości komentarze to takie które:

  • opisują za co odpowiada metoda, jednocześnie rozmijając się z prawdą zawartą w implementacji 😈,
  • tłumaczą podstawowe operacje (poniżej fragment mojego starego kodu),
  • objaśniają zawiłość rozwiązania zamiast konkretnie odnieść użytkownika, że wykorzystaliśmy algorytm A*,
  • informują, że zmienna $firstName zawiera imię,
  • „wycinają funkcjonalność” poprzez zakomentowanie kodu,
  • pełnią rolę historii zmian.
❗️ Tym komentarzom mówimy stanowcze NIE. ❗️

Długo by wymieniać. Sam dawno temu, zostawiłem w kodzie sporo podobnych smaczków myśląc, że wniosą one pożyteczną wartość do projektu:

// Load link by hash
$link = ORM::factory('link', $this->request->param('hash'));

// Throw exception if link not exists
if (!$link->loaded()) {
    throw new Exception('Link not exists!');
}

// Increment redirections and update DB
$link->redirections += 1;
$link->save();

// Redirect to url
$this->request->redirect($link->url, 301);

Dziś wywołują jedynie uśmiech na twarzy, przypominając mi, że od razu nie było się orłem 🙂

Wartościowe, uzupełniające kod ✔️

Tych dobrych komentarzy, wartych uwagi programisty jest zdecydowanie mniej. Jednak w tym tkwi ich potencjał.

1. Wyjaśniające decyzję, kontekst

Zostawiając komentarz dlaczego w naszym przypadku zastosowaliśmy algorytm A*. Szczególnie gdy wyjaśnienie nie jest zawarte bezpośrednio w kodzie, ale umieszczony został link – do dokumentacji, strony internetowej.

Czasem musimy walczyć z frameworkami oraz konkretnymi wersjami przeglądarek:

// Fix IE Caching Issue: http://stackoverflow.com/a/19771501
if (!$httpProvider.defaults.headers.get) {
    $httpProvider.defaults.headers.get = {};
}

Wiadomo przynajmniej skąd to dziwadło znalazło się w kodzie.

2. @TODO

Oznaczenie fragmentów kodu do których musimy wrócić w przyszłości (z różnych względów). Szczególnie gdy mamy do czynienia z Feature Flags, prosty zabieg ułatwi nam odnalezienie wszystkich użytych Feature Flags w kodzie projektu. Tym bardziej, że IDE bardzo sprawnie radzi sobie z wyszukiwaniem tego typu komentarzy. Można posługiwać się szablonem: // @TODO FF:[TICKET ID / FEATURE FLAG ID] czyli: // @TODO FF:AUDITOR-276.

Zazwyczaj są to komentarze o określonej długości życia – znikają wraz z usprawnieniem kodu / usunięciem Feature Flag.

3. Komentarze na potrzeby publicznego API

Czyli komentarze na podstawie których możemy wygenerować dokumentację – fajnym przykładem jest API dla SDK AWS. Wykorzystywanie IDE ułatwia także wykorzystywanie API biblioteki, podpowiadając nam niezbędną składnię.

Tutaj czai się jednak to o czym wspomniałem na początku. Łatwo zmienić implementację, pozostawiając niezmienioną formę komentarza – przynajmniej tą opisową, bo z typami oraz nazwami parametrów metody, narzędzia SCA sobie nieźle radzą. Tak więc nawet dobry komentarz, może przybrać formę komentarza niechcianego w naszym kodzie 🙁

Nie bój się dobrych komentarzy w kodzie

Chciałbym zwrócić uwagę, że minimalizowanie szumu w kodzie, nie wiąże się bezpośrednio z usunięciem wszystkiego co jest komentarzem. Jak widać, w gąszczu złych komentarzy, znajdziemy także ich formę, która przynosi wartość – jest ich jak na lekarstwo ale jednak. W gruncie rzeczy, gdyby komentarze były bezużyteczne – dawno zniknęłyby z naszych języków programowania. Ah… zagalopowałem się, goto wprowadzono do języka PHP dopiero w wersji PHP 5.3 wydanej w 2009 roku 👌

Mówi się, że testy jednostkowe są dokumentacją dla programisty. Dobre komentarze – mogą ją nieco uzupełniać, dając trochę więcej kontekstu na podjęte decyzje.

Na co dzień programujący CTO w Emphie Solutions. Projektuje, tworzy oraz wdraża rozwiązania oparte o ekosystem JavaScript. Rozwija swoje umiejętności z zakresu Cloud / DevOps / SRE. Fascynat programowania, architektury, chmury i dobrych praktyk w szerokim ujęciu. Na temat technologii publikuje materiały w ramach projektu DevEnv, którego jest założycielem.
PODZIEL SIĘ