Mój współpracownik uważa, że każde użycie komentarzy w kodzie (tj. Nie metoda w stylu javadoc lub komentarze do klasy) to zapach kodu . Co myślisz?
Mój współpracownik uważa, że każde użycie komentarzy w kodzie (tj. Nie metoda w stylu javadoc lub komentarze do klasy) to zapach kodu . Co myślisz?
Odpowiedzi:
Tylko jeśli komentarz opisuje, co robi kod.
Gdybym chciał wiedzieć, co dzieje się w metodzie lub bloku, przeczytałbym kod. W każdym razie mam nadzieję, że wszyscy programiści pracujący nad danym projektem byli przynajmniej na tyle obeznani z językiem programowania, aby przeczytać to, co jest napisane i zrozumieć, co robi.
W niektórych przypadkach skrajnej optymalizacji możesz używać technik, które utrudniają komuś śledzenie tego, co robi Twój kod. W takich przypadkach można i należy wykorzystać komentarze, aby nie tylko wyjaśnić, dlaczego masz takie optymalizacje, ale także to, co robi kod. Dobrą zasadą byłoby, aby ktoś inny (lub wiele innych osób) zapoznał się z językiem implementacji i spojrzeniem projektu na Twój kod - jeśli nie rozumieją zarówno przyczyny, jak i sposobu, powinieneś skomentować zarówno dlaczego, jak i jak.
Jednak w kodzie nie jest jasne, dlaczego coś zrobiłeś. Jeśli podejmiesz podejście, które może nie być oczywiste dla innych, powinieneś mieć komentarz wyjaśniający, dlaczego podjąłeś decyzje, które podjąłeś. Podejrzewam, że możesz nawet nie zdawać sobie sprawy, że komentarz jest potrzebny dopiero po czymś takim jak przegląd kodu, gdzie ludzie chcą wiedzieć, dlaczego zrobiłeś X zamiast Y - możesz zapisać swoją odpowiedź w kodzie dla wszystkich, którzy na nią patrzą w przyszłości.
Najważniejszą rzeczą jest jednak zmiana komentarzy podczas zmiany kodu. Jeśli zmienisz algorytm, pamiętaj, aby zaktualizować komentarze, dlaczego użyłeś algorytmu X zamiast Y. Komentarze stale są jeszcze większym zapachem kodu.
Jest to szczególnie irytujące, gdy słyszę, że spędziłem trochę czasu w ten weekend, patrząc na bardzo dobrze nazwany, bardzo czysty, niezakomentowany kod implementujący algorytm badawczy (taki, który nie został opublikowany). Znam go na wysokim poziomie, facet siedzący obok mnie był wynalazcą, a kod został napisany kilka lat temu przez kogoś innego. Ledwie mogliśmy to zrobić.
Twój współpracownik nie ma oczywiście wystarczającego doświadczenia.
Komentarze powinny wyjaśniać dlaczego, a nie jak.
How
komentarze typu są zazwyczaj lepiej rozpatrywane przy użyciu refaktoryzacji. Osobiście zwykle unikam komentarzy na rzecz refaktoryzacji.
Przed:
# convert to cents
a = x * 100
# avg cents per customer
avg = a / n
# add to list
avgs < avg
t += 1
po:
total_cents = total * 100
average_per_customer = total_cents / customer_count
track_average(average_per_customer)
Ogłaszam, że twój współpracownik jest heretykiem! Gdzie są moje płonące heretyki?
Obsesyjne komentowanie jest złe i powoduje ból głowy, a komentarze nie zastępują dobrze nazwanych metod, klas, zmiennych itp. Ale czasami wyjaśnianie, dlaczego coś takiego jest, może być niezwykle cenne dla biednego idioty, który musi utrzymywać kod za sześć miesięcy - szczególnie, gdy ten biedny idiota kończy na tobie.
Kilka faktycznych komentarzy z kodu, nad którym pracuję:
// If this happens, somebody's been screwing around with the database definitions and
// has removed the restriction that a given alarm may have only one entry in the
// notifications table. Bad maintenance programmer! Bad! No biscuit!
// If an alert is active on our side but inactive on theirs, that might mean
// they closed the alert. (Or that we just haven't told them about it yet.) The
// logic comes later; for now, we'll just compile it in a list.
// If we know for a fact that an alarm isn't getting through, we're going to whine pretty
// aggressively about it until it gets fixed.
Idealnie byłoby, gdyby kod był tak dobrze zakodowany, aby mógł być auto-objaśniający. W prawdziwym świecie wiemy, że również bardzo wysokiej jakości kod wymaga czasem komentarza.
To, czego absolutnie powinieneś unikać, to „redundancja kodu komentarza” (komentarze, które niczego nie dodają do kodu):
i++; // Increment i by 1
Następnie, jeśli istnieje dobry (i utrzymany / wyrównany) projekt i dokumentacja kodu, komentowanie jest jeszcze mniej przydatne.
Ale w niektórych okolicznościach komentarze mogą być dobrą pomocą w czytaniu kodu:
while( foo )
{
if( dummy )
{
}
else // !dummy
{
}
} // end while( foo )
Nie zapominaj, że musisz utrzymywać i synchronizować także komentarze ... nieaktualne lub błędne komentarze mogą być strasznym bólem! I z reguły zbyt wiele komentarzy może być objawem złego programowania.
} //end while
oznacza tylko, że początek pętli while jest tak daleko, że nawet jej nie widzisz, i nie ma żadnych wskazówek, że kod, który oglądasz, znajduje się w pętli. Ciężkie refaktoryzacja powinna być poważnie preferowana w stosunku do komentarzy na temat struktury kodu.
} // end while
komentarze mogą uratować życie.
Kategoryczne zdefiniowanie metody lub procesu jako „zapachu kodu” jest „zapachem gorliwości”. Termin ten staje się nowy „uważany za szkodliwy”.
Pamiętaj, że wszystkie tego rodzaju rzeczy mają być wytycznymi.
Wiele innych odpowiedzi daje dobrą radę, kiedy uzasadnione są komentarze.
Osobiście używam bardzo niewielu komentarzy. Wyjaśnij cel nieoczywistych procesów i pozostaw sporadyczną groźbę śmierci każdemu, kto może rozważać samodzielną zmianę rzeczy, która wymagałaby tygodni tuningu.
Przeredagowanie wszystkiego, dopóki przedszkolak nie zrozumie, że prawdopodobnie nie jest to wydajne wykorzystanie twojego czasu i prawdopodobnie nie będzie działać tak dobrze, jak bardziej zwięzła wersja.
Komentarze nie wpływają na czas działania, więc jedynym negatywnym problemem do rozważenia jest konserwacja.
W niektórych przypadkach żadna ilość dobrego nazewnictwa, refaktoryzacji itp. Nie może zastąpić komentarza. Spójrz na ten przykład z prawdziwego świata (językiem jest Groovy):
response.contentType="text/html"
render '{"success":true}'
Wygląda dziwnie, prawda? Prawdopodobnie błąd kopiowania-wklejenia? Woła o poprawkę?
Teraz to samo z komentarzami:
// DO NOT TOUCH THE FOLLOWING TWO LINES; the ExtJS UploadForm requires it exactly like that!!!
response.contentType="text/html" // must be text/html so the browser renders the response within the invisible iframe, where ExtJS can access it
render '{"success":true}' // ExtJS expects that, otherwise it will call the failure handler instead of the succss handler
Podstawową kwestią jest tutaj znaczenie terminu „zapach kodu”.
Myślę, że wiele osób (łącznie z tobą) rozumie zapach kodu jako coś bliskiego błędu lub przynajmniej coś, co należy naprawić. Być może myślisz o tym jako o synonimie „anty-wzorca”.
To nie jest znaczenie tego terminu!
Metafora zapachu kodu pochodzi z Wiki Wards i podkreślają:
Zauważ, że CodeSmell to wskazówka, że coś może być nie tak, a nie pewność. Idealnie dobry idiom można uznać za CodeSmell, ponieważ często jest niewłaściwie używany lub ponieważ istnieje prostsza alternatywa, która działa w większości przypadków. Nazywanie czegoś CodeSmell nie jest atakiem; to po prostu znak, że uzasadnione jest bliższe spojrzenie.
Co to znaczy, że komentarze są zapachem kodu: oznacza to, że kiedy zobaczysz komentarz, powinieneś zatrzymać się i pomyśleć: „Hmmm, wyczuwam wskazówkę, że coś można poprawić”. Być może możesz zmienić nazwę zmiennej, wykonać „metodę wyodrębniania” - refaktoryzacja - a może komentarz jest w rzeczywistości najlepszym rozwiązaniem.
EDYCJA: Właśnie natknąłem się na te dwa artykuły, co wyjaśnia to lepiej niż ja:
Myślę, że zasada jest dość prosta: wyobraź sobie, że twój nieznajomy widzi twój kod. Twój kod prawdopodobnie będzie Ci obcy za 5 lat. Spróbuj zminimalizować wysiłek umysłowy, aby zrozumieć swój kod dla tego nieznajomego.
Dobrym pomysłem na właściwe komentarze jest rozpoczęcie pisania komentarzy.
// This function will do something with the parameters,
// the parameters should be good according to some rules.
myFunction(parameters)
{
// It will do some things to get started.
// It will do more with the stuff.
// It will end doing things with the stuff.
}
Pozwala to łatwo wyodrębnić metody, aby nawet pozbyć się komentarzy,
po prostu pozwól kodowi powiedzieć te rzeczy ! Zobacz, jak to jest przepisane (wytnij / wklej) w bardzo przyjemny sposób:
// This function will do something with the parameters,
// the parameters should be good according to some rules.
myfunction(parameters)
{
var someThing = initializedWithSomething;
doSomethingWith(someThing);
doMoreWith(someThing);
endDoingThingsWith(someThing);
return someThing;
}
// This function will do some things to get started,
// the parameters should be good according to some rules.
doSomethingWith(parameters)
{
parameters.manipulateInSomeWay();
... etc ...
}
... etc ...
W przypadku rzeczy, których nie można rozdzielić, po prostu nie wyodrębniaj metod i wpisz kod pod komentarzami.
To, co uważam za użyteczny sposób ograniczania komentarzy do minimum, naprawdę bezużyteczne jest komentowanie każdej linii ... Dokumentuj tylko jedną linię, jeśli dotyczy inicjalizacji wartości magicznej lub tam, gdzie ma to sens.
Jeśli parametry są używane zbyt często, powinni być prywatnymi członkami twojej klasy.
Myślę, że odpowiedź brzmi: „To zależy”. Komentowanie kodu, aby skomentować kod, to zapach. Komentowanie kodu, ponieważ używasz niejasnego algorytmu, który jest o rząd wielkości, szybciej oszczędza programistom konserwacji (zwykle mnie 6 miesięcy po napisaniu go) pół dnia przeszukiwania kodu w celu ustalenia, co robi.
// Dear me in the future. Please, resolve this problem.
lub
// You think this code was written by somebody else.
// No, it wasn't. You ([some name]) did it.
Komentarze do kodu zdecydowanie nie są „zapachem kodu”. Przekonanie to zazwyczaj wynika z faktu, że komentarze mogą stać się nieaktualne (nieaktualne) i mogą być trudne do utrzymania. Jednak dobre komentarze wyjaśniające, dlaczego kod robi coś w określony sposób, mogą (i zwykle są) ważne dla konserwacji.
Dobre komentarze ułatwiają zrozumienie tego, co robi kod i, co ważniejsze, dlaczego robi to w określony sposób. Komentarze mają być czytane przez programistów i powinny być jasne i precyzyjne. Komentarz, który jest trudny do zrozumienia lub niepoprawny, nie jest dużo lepszy niż brak komentarza.
Dodanie jasnych i precyzyjnych komentarzy do kodu oznacza, że nie musisz polegać na pamięci, aby zrozumieć „co” i „dlaczego” w części kodu. Jest to najważniejsze, gdy spojrzysz na ten kod później lub ktoś inny musi na niego patrzeć. Ponieważ komentarze stają się częścią tekstowej zawartości twojego kodu, powinny być zgodne z dobrymi zasadami pisania, oprócz tego, że są napisane jasno.
Aby napisać dobry komentarz, powinieneś dołożyć wszelkich starań, aby udokumentować cel kodu (dlaczego, a nie jak) oraz wskazać rozumowanie i logikę stojącą za kodem tak jasno, jak to możliwe. Idealnie, komentarze powinny być pisane w tym samym czasie, w którym piszesz kod. Jeśli zaczekasz, prawdopodobnie nie wrócisz i nie dodasz ich.
Sams Teach Your Visual C # 2010 w ciągu 24 godzin , s. 348–349.
Jeśli kod został napisany w określony sposób, aby uniknąć problemu w bibliotece (zarówno w bibliotece innej firmy, jak i bibliotece dostarczanej z kompilatorem), warto go skomentować.
Sensowne jest także komentowanie kodu, który należy zmienić w przyszłych wersjach lub podczas korzystania z nowej wersji biblioteki lub na przykład podczas przechodzenia z PHP4 do PHP5.
Nawet najbardziej dobrze napisana książka prawdopodobnie zawiera tytuły wstępu i rozdziałów. Komentarze w dobrze udokumentowanym kodzie są nadal przydatne do opisywania pojęć wysokiego poziomu i wyjaśniania, w jaki sposób kod jest zorganizowany.
Nie zgadzam się z pomysłem, że pisanie komentarzy w celu wyjaśnienia kodu jest złe. To całkowicie ignoruje fakt, że kod zawiera błędy. Może być jasne, co robi kod bez komentarzy. Jest mniej prawdopodobne, aby być jasne, jaki kod jest niby zrobić . Bez komentarzy, skąd wiesz, czy wyniki są nieprawidłowe, czy są nieprawidłowo wykorzystywane?
Komentarze powinny wyjaśniać zamiar kodu, aby w przypadku pomyłki ktoś czytający komentarze + kod miał szansę go znaleźć.
Zazwyczaj piszę wbudowane komentarze przed napisaniem kodu. W ten sposób jasne jest, co próbuję napisać, i zmniejsza zagubienie się w algorytmie, nie wiedząc naprawdę, co próbujesz zrobić.
Komentarze, które są wstawiane, ponieważ ktoś uważa, że posiadanie 700 linii w jednej metodzie jest w porządku, to zapach.
Komentarze, które tam są, ponieważ wiesz, że jeśli nie dodasz komentarza, ktoś popełni ten sam błąd po raz kolejny to zapach.
Komentarze zostały wstawione, ponieważ niektóre narzędzia do analizy kodu wymagają, aby był to także zapach.
Ludzie, którzy nigdy nie dodadzą komentarza ani nie piszą żadnej pomocy dla innych programistów, również pachną. Dziwi mnie, jak wiele osób nie zapisuje rzeczy, ale potem odwraca się i potwierdzam, że nie pamiętają, co zrobili 3 miesiące temu. Nie lubię pisać dokumentów, ale lubię ciągle powtarzać ludziom to samo.
Odpowiem na własne pytanie. Czy możesz znaleźć błąd w nieskomentowanym kodzie poniżej?
tl; dr: Następna osoba, która utrzyma twój kod, może nie być tak podobna do boga jak ty.
[org 0x7c00]
main:
mov ah, 0x0e
mov bx, string
call strreverse
call print
stop:
jmp $
strreverse:
pusha
mov dx, bx
mov cx, 0
strreverse_push:
mov al, [bx]
cmp al, 0
je strreverse_pop
push ax
add bx, 1
add cx, 1
jmp strreverse_push
strreverse_pop:
mov bx, dx
strreverse_pop_loop:
cmp cx, 0
je strreverse_end
pop ax
mov [bx], al
sub cx, 1
add bx, 1
jmp strreverse_pop_loop
strreverse_end:
popa
ret
print:
pusha
print_loop:
mov al, [bx]
cmp al, 1
je print_end
int 0x10
add bx, 1
jmp print_loop
print_end:
popa
ret
string:
db 'Boot up', 0
times 510 -( $ - $$ ) db 0
dw 0xaa55
Musisz zachować równowagę między kodem a komentarzami ... Zwykle staram się dodawać komentarze, które wznawiają blok kodu. Nie dlatego, że nie będę w stanie zrozumieć kodu (no cóż, to też), ale dlatego, że mogę szybciej czytać własny kod i znajdować określone sekcje, w których dzieją się ważne rzeczy.
W każdym razie moje własne kryteria to „w razie wątpliwości komentuj”. Wolę mieć nadmiarową linię niż całkowicie tajemniczą linię, której nie będę w stanie zrozumieć. Zawsze mogę po pewnym czasie usunąć komentarze do recenzji kodu (i zwykle tak robię)
Ponadto komentarze są bardzo pomocne, dodając „zastrzeżenia”, takie jak „Uważaj! Jeśli formatem wejściowym nie jest ASCII, ten kod będzie musiał się zmienić!”
Myślę, że komentowanie kodu ma bardzo słaby początek. Nie wiem o tych dniach, ale kiedy po raz pierwszy uczyłem się programowania w szkole, dostałem zadania w rodzaju „Napisz program, który drukuje liczby od jeden do dziesięciu w osobnych wierszach. Pamiętaj o skomentowaniu kodu”. Zostaniesz oznaczony, jeśli nie dodasz komentarzy, ponieważ komentowanie kodu to DOBRA RZECZ.
Ale co można powiedzieć o tak trywialnym procesie? W rezultacie piszesz klasykę
i++; // add one to the "i" counter.
tylko po to, aby uzyskać przyzwoitą ocenę i, jeśli masz jakieś złe, natychmiast formułować bardzo niską opinię o komentarzach do kodu.
Komentowanie kodu nie jest DOBREJ RZECZY. TO CZASEM NIEZBĘDNE RZECZY, a Thomas Owens w pierwszej odpowiedzi stanowi doskonałe wyjaśnienie sytuacji, w których jest to konieczne. Jednak sytuacje te rzadko pojawiają się w zadaniach domowych.
Pod wieloma względami dodanie komentarza należy uznać za ostateczny wybór, gdy tego, co należy powiedzieć, nie można jasno powiedzieć w aktywnych częściach języka programowania. Chociaż nazewnictwo obiektów może być nieaktualne, różne mechanizmy braku sprzężenia zwrotnego od ludzi i komputerów ułatwiają zapominanie o utrzymywaniu komentarzy, w wyniku czego komentarze stają się nieaktualne znacznie szybciej niż aktywny kod. Z tego powodu, tam gdzie możliwy jest wybór, zawsze należy preferować zmianę kodu, aby był bardziej przejrzysty, niż dodawanie do niejasnego kodu komentarzy.
każdy programista wie, że w końcu wszyscy oszaleliśmy powodu pracy, debugowania lub zwykłego szaleństwa, na które wpadamy.
"Zrób to!" mówi kierownik projektu.
Odpowiadasz: „Tego nie da się zrobić”.
Mówią: „W takim razie znajdziemy kogoś innego”.
Mówicie: „OK, cóż, może da się to zrobić”.
A następnie spędzić następną liczbę dni X .. tygodni .. miesięcy .. próbując to rozgryźć. W trakcie tego procesu będziesz próbować i nie powiedzie się, i spróbujesz i nie powiedzie się. Wszyscy to robimy.Prawdziwa odpowiedź jest taka, że istnieją dwa typy programistów: ci, którzy komentują i ci, którzy nie komentują.
1) Ci, którzy to robią, albo ułatwiają własną pracę, dokumentując na przyszłość, komentując nieudane procedury, które nie działały (zapach nie usuwa ich po znalezieniu tej, która działa) lub łamią kod z komentarzem formatowanie, które, miejmy nadzieję , nieco ułatwi czytanie lub zrozumienie. Poważnie, nie mogę ich winić. Ale w końcu pękają, a potem masz to:
// dammit this code sucks! swear! curse! i hate it! i am going to write something here to vent my anger!!!!
2) Ci, którzy nie udają superbohatera lub żyją w jaskini . Po prostu lekkomyślnie lekceważą innych i siebie, i mogą mniej przejmować się kodem lub jego znaczeniem na później.
Nie zrozumcie mnie źle… zmienne i funkcje samodokumentujące mogą tego całkowicie uniknąć… i wierzcie mi, że nigdy nie można zrobić wystarczająco dużo czyszczenia kodu. Ale prosta prawda jest taka, że dopóki przechowujesz kopie zapasowe, możesz ZAWSZE usuwać komentarze.
Twierdziłbym, że niestosowanie niektórych komentarzy w kodzie to zapach kodu. Chociaż zgadzam się, że kod powinien samokontraktować się w jak największym stopniu, osiągnąłeś punkt, w którym zobaczysz kod, który nie ma sensu bez względu na to, jak dobrze kod jest napisany. W aplikacjach biznesowych widziałem kod, w którym komentarze są obowiązkowe, ponieważ:
Przewodniki w stylu firmowym mogą również zalecić zrobienie czegoś w określony sposób - jeśli mówią, że powinieneś mieć komentarze określające, co robią bloki kodu w funkcji, dołącz komentarze.
Istnieje duża fundamentalna różnica między komentarzami a kodem: komentarze są sposobem, w jaki ludzie mogą przekazywać pomysły innym ludziom, podczas gdy kod jest przeznaczony głównie dla komputera. W „kodzie” jest wiele aspektów, które dotyczą tylko ludzi, na przykład nazywanie nazw i wcięcia. Ale komentarze są napisane wyłącznie dla ludzi, przez ludzi.
Dlatego pisanie komentarzy jest tak samo trudne, jak każda pisemna komunikacja ludzka! Autor powinien mieć jasne pojęcie o tym, kim jest publiczność i jakiego rodzaju tekstu będzie potrzebował. Skąd możesz wiedzieć, kto przeczyta twoje komentarze za dziesięć, dwadzieścia lat? Co jeśli osoba pochodzi z zupełnie innej kultury? Itd. Mam nadzieję, że wszyscy to rozumieją.
Nawet w małej homogenicznej kulturze, w której żyję, tak trudno jest przekazywać pomysły innym ludziom. Komunikacja ludzka zwykle kończy się niepowodzeniem, z wyjątkiem przypadku.
Muszę się zgodzić z twoim współpracownikiem. Zawsze mówię, że jeśli skomentuję mój kod, oznacza to, że martwię się, że nie będę w stanie wymyślić własnego kodu w przyszłości. To zły znak.
Jedynym innym powodem, dla którego umieszczam komentarze w kodzie, jest wywołanie czegoś, co wydaje się nie mieć sensu.
Te komentarze zwykle mają formę:
//xxx what the heck is this doing??
lub
// removed in version 2.0, but back for 2.1, now I'm taking out again
Komentarze do kodu podające, w stosownych przypadkach, jednostki argumentów i zwrotów funkcji, pola struktury, a nawet zmienne lokalne mogą być bardzo przydatne. Pamiętaj o Mars Orbiter!
Poinformuj swojego współpracownika o technice programowania literackiego .
Nie, komentarze nie są zapachem kodu, są tylko narzędziem, które można wykorzystać.
Przykłady dobrych komentarzy:
// Myślę, że to jest w cm. Konieczne dalsze dochodzenie!
// To sprytny sposób wykonywania X
// Lista nie może być tutaj pusta
Assert(list.IsEmpty)
?
Assert(!list.isEmpty())
nie jest dokładnie umową jak w trzecim komentarzu, ale po prostu zachowaniem (tj. „Wyrzuć IllegalArgumentException, jeśli argument jest pusty”), który musi być testowany jednostkowo, jak każda inna logika programu. Zwróć uwagę na subtelną różnicę w komentarzu, która określa, kiedy można zastosować metodę, ale nie określa zachowania, jeśli warunek wstępny nie jest spełniony. Jeszcze lepszym rozwiązaniem byłoby egzekwowanie umów na czas kompilacji. Ale to przekracza zakres mojej odpowiedzi;)
Assert
s, ponieważ opisują rzeczy, które nigdy nie powinny się zdarzyć, nawet jeśli publiczny interfejs API otrzyma nieprawidłowe argumenty.