Cytat Roberta C. Martina jest wyjęty z kontekstu. Oto cytat z nieco większym kontekstem:
Nic nie może być tak pomocne, jak dobrze umieszczony komentarz. Nic nie może zagracać modułu bardziej niż frywolne dogmatyczne komentarze. Nic nie może być tak szkodliwe, jak stary, szorstki komentarz, który propaguje kłamstwa i dezinformację.
Komentarze nie są jak Lista Schindlera. Nie są „czystym dobrem”. Rzeczywiście, komentarze są w najlepszym razie złem koniecznym. Gdyby nasze języki programowania były wystarczająco wyraziste lub gdybyśmy mieli talent do subtelnego posługiwania się tymi językami, aby wyrazić naszą intencję, nie potrzebowalibyśmy zbyt wiele komentarzy - być może wcale.
Właściwe użycie komentarzy ma zrekompensować nam brak wyrażenia się w kodzie. Zauważ, że użyłem słowa brak. Miałem to na myśli. Komentarze są zawsze błędami. Musimy je mieć, ponieważ nie zawsze możemy dowiedzieć się, jak wyrazić się bez nich, ale ich użycie nie jest powodem do świętowania.
Więc kiedy znajdziesz się w sytuacji, w której musisz napisać komentarz, zastanów się i sprawdź, czy nie ma sposobu, aby zmienić tabele i wyrazić się w kodzie. Za każdym razem, gdy wyrażasz się w kodzie, powinieneś poklepać się po plecach. Za każdym razem, gdy piszesz komentarz, powinieneś skrzywić się i czuć brak umiejętności wyrażania.
(Skopiowano z tego miejsca , ale oryginalny cytat pochodzi z Clean Code: A Handbook of Agile Software Craftsmanship )
To, jak ten cytat sprowadza się do „Komentarze są zawsze porażkami”, jest dobrym przykładem tego, jak niektórzy ludzie wyciągną rozsądny cytat z kontekstu i zamieni go w głupi dogmat.
Dokumentacja API (jak javadoc) ma udokumentować API, aby użytkownik mógł z niego korzystać bez konieczności odczytywania kodu źródłowego . W takim przypadku dokumentacja powinna wyjaśniać, co robi metoda. Teraz możesz argumentować, że „Pobiera produkt według jego identyfikatora” jest zbędny, ponieważ jest już wskazany przez nazwę metody, ale informacje, które null
można zwrócić, są zdecydowanie ważne w dokumentacji, ponieważ nie jest to w żaden sposób oczywiste.
Jeśli chcesz uniknąć konieczności komentarza, musisz usunąć podstawowy problem (którym jest użycie null
jako prawidłowej wartości zwracanej), czyniąc interfejs API bardziej wyraźnym. Na przykład możesz zwrócić jakiś rodzaj Option<Product>
, więc sam podpis typu wyraźnie informuje, co zostanie zwrócone, jeśli produkt nie zostanie znaleziony.
Ale w każdym razie nie jest realistyczne udokumentowanie API w pełni tylko poprzez nazwy metod i podpisy typów. Użyj komentarzy do wszelkich dodatkowych nieoczywistych informacji, które użytkownik powinien wiedzieć. Załóżmy, że dokumentacja API z DateTime.AddMonths()
BCL:
Metoda AddMonths oblicza wynikowy miesiąc i rok, biorąc pod uwagę lata przestępne i liczbę dni w miesiącu, a następnie dostosowuje część dzienną wynikowego obiektu DateTime. Jeśli wynikowy dzień nie jest prawidłowym dniem w wynikowym miesiącu, używany jest ostatni ważny dzień wynikowego miesiąca. Na przykład 31 marca + 1 miesiąc = 30 kwietnia. Część czasu wynikowego obiektu DateTime pozostaje taka sama jak to wystąpienie.
Nie ma możliwości wyrażenia tego za pomocą nazwy i podpisu metody! Oczywiście twoja dokumentacja klasowa może nie wymagać takiego poziomu szczegółowości, to tylko przykład.
Komentarze wbudowane też nie są złe.
Złe komentarze są złe. Na przykład komentarze, które wyjaśniają tylko to, co można w prosty sposób zobaczyć z kodu, klasycznym przykładem jest:
// increment x by one
x++;
Komentarze, które wyjaśniają coś, co można wyjaśnić przez zmianę nazwy zmiennej lub metody lub w inny sposób restrukturyzację kodu, to zapach kodu:
// data1 is the collection of tasks which failed during execution
var data1 = getData1();
Takie są uwagi, które Martin szykuje. Komentarz jest symptomem braku napisania czystego kodu - w tym przypadku należy użyć zrozumiałych nazw dla zmiennych i metod. Sam komentarz oczywiście nie jest problemem, problem polega na tym, że potrzebujemy komentarza, aby zrozumieć kod.
Ale komentarze powinny być użyte do wyjaśnienia wszystkiego, co nie jest oczywiste z kodu, np. Dlaczego kod jest napisany w pewien nieoczywisty sposób:
// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();
Komentarze, które wyjaśniają, co robi nadmiernie skomplikowany fragment kodu, są również zapachem, ale poprawka nie polega na zakazaniu komentarzy, poprawka polega na naprawieniu kodu! Mówiąc inaczej, zdarza się zawiły kod (miejmy nadzieję, że tylko tymczasowo do momentu refaktoryzacji), ale żaden zwykły programista nie pisze za pierwszym razem idealnego czystego kodu. Kiedy zdarza się zawiły kod, znacznie lepiej jest napisać komentarz wyjaśniający, co robi, niż nie pisać komentarza. Ten komentarz ułatwi również później refaktoryzację.
Czasami kod jest nieuchronnie złożony. Może to być skomplikowany algorytm lub kod zmniejszający przejrzystość ze względu na wydajność. Ponownie komentarze są konieczne.