Jaki jest dobry sposób na komentowanie klauzul if-else? [Zamknięte]

15

Ilekroć piszę typową konstrukcję typu if-else w jakimkolwiek języku, zastanawiam się, jaki byłby najlepszy sposób (pod względem czytelności i przeglądu) dodawania do niej komentarzy. Szczególnie, gdy komentuję klauzulę else, komentarze zawsze wydają mi się nie na miejscu. Powiedzmy, że mamy taką konstrukcję (przykłady są zapisane w PHP):

if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}

Mógłbym to skomentować w ten sposób:

// check, what kind of magic should happen
if ($big == true) {
    // do some big magic stuff
    bigMagic();
} else {
    // small magic is enough
    smallMagic()
}

lub

// check, what kind of magic should happen
// do some big magic stuff
if ($big == true) {
    bigMagic();
}
// small magic is enough
else {
   smallMagic()
}

lub

// check, what kind of magic should happen
// if:   do some big magic stuff
// else: small magic is enough
if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}

Jakie są najlepsze praktyki dotyczące komentowania tego?

kulminacja
źródło
8
else { // for future reader: sorry, at the moment of writing this I did not have time and skills to come up with a better way to express my logic
komar
1
Dlaczego Bigger jest lepszy / preferowany / inny? Nie wiem.
JeffO
Czy to temat na pytanie czy kłótnię? Nawet jeśli pytanie jest słuszne, są one początkiem wojny.
Niezależny
1
Interesujące jest dla mnie to, że tak wielu ludzi uważało, że na to pytanie warto było odpowiedzieć, ale nie było warte wznowienia głosowania. Chociaż interesują mnie odpowiedzi (moja jest jedyną +1), pytanie wydaje się być kwintesencją przykładu problemu zrzucenia roweru.
canisrufus
1
@canisrufus Tak to wygląda tylko dlatego, że niższe głosy równoważą wyższe głosy. W tej chwili jest 6 głosów w górę i 4 głosy w dół za netto +2.
Caleb

Odpowiedzi:

34

Wolę:

if ($magic == big) {
    bigMagic();
}
else {
    smallMagic();
}

lub:

if ($magic == big) {
    // big magic requires a big surprise, so I'm telling you about it here
    surprisingThing();
}
else {
    // give a magical feeling even if $magic is noMagicAtAll
    smallMagic();
}

Trochę głupio wydaje się napisanie komentarza wyjaśniającego, co sprawdza twój stan, chyba że kod wyraźnie tego nie określa. Nawet wtedy lepiej przepisać kod, aby był jak najbardziej przejrzysty. To samo dotyczy brył bloków warunkowych - jeśli możesz podać powód zrobienia czegoś oczywistego, zrób to zamiast komentowania.

Nie zgadzam się z filozofią „nigdy nie pisz komentarzy”, ale wierzę w unikanie komentarzy, które mówią, co powinien zawierać kod. Jeśli napiszesz komentarz w rodzaju „sprawdź, jaka magia powinna się wydarzyć”, kiedy kod mógłby powiedzieć if ($magic == big) {..., czytelnicy przestaną czytać twoje komentarze bardzo szybko. Używanie mniejszej liczby bardziej znaczących komentarzy nadaje każdemu twojemu komentarzowi większą wartość, a czytelnicy znacznie częściej zwracają uwagę na te, które piszesz.

Ważne jest wybranie znaczących nazw dla zmiennych i funkcji. Dobrze wybrana nazwa może wyeliminować potrzebę komentarzy wyjaśniających w całym kodzie. W twoim przykładzie, $magica może $kindOfMagicwydaje się lepszym imieniem niż, $bigponieważ według twojego przykładu, to „rodzaj magii” jest testowany, a nie „wielka” coś.

Powiedz tyle, ile możesz w kodzie. Zachowaj prozę dla przypadków, które wymagają więcej wyjaśnień niż można rozsądnie napisać w kodzie.

Caleb
źródło
13
+1 nie przesadzaj z komentarzami, czysty kod nie wymaga komentarzy
maniak ratchet
3
@ratchetfreak Wydaje się, że jesteśmy w większości zgodni, ale komentarze są często konieczne, aby kod był wyraźniejszy. Zapewnianie kontekstu historycznego, wyjaśnianie zaskakujących zachowań lub rozwiązywanie dwuznaczności najlepiej jest wykonywać za pomocą komentarzy.
Caleb
1
Dobra uwaga, Caleb. To prawda, że ​​kod powinien sam się komentować tak długo, jak to możliwe.
acme
7
Dobre komentarze nie wyjaśniają, co - „sprawdź, jaka magia powinna się wydarzyć” - wyjaśniają dlaczego, tj. „Użytkownicy mogą wybrać rodzaj magii do uruchomienia” lub „Usługa wypełni dużą magię, jeśli są dostępne, więc musimy sprawdzić typ ”lub cokolwiek innego. Bez względu na to, jak dobre jest twoje kodowanie, dlaczego nie znają tych, którzy nie znają reguł biznesowych.
Bruno Brant
1
Problem polega na tym, że najłatwiej jest napisać trudny do odczytania kod, a nie komentować. Łatwiej jest też pisać trudny do odczytania kod, ale dobrze go komentować niż konsekwentnie pisać kod tak dobrze, że nie potrzebuje komentarzy.
asfallows
11

Wypróbuj objaśniające nazwy zmiennych

Komentarze mogą być świetne, ale jeśli to możliwe, spraw, aby kod sam się dokumentował. Jednym ze sposobów na to jest objaśnianie nazw zmiennych. Na przykład zamiast tego:

if (user.has_sideburns && user.can_gyrate) {
  // This user is a potential Elvis impersonator

}

Wolałbym nazwaną zmienną:

is_potential_elvis_impersonator = user.has_sideburns && user.can_gyrate

if (is_potential_elvis_impersonator) {
  ...
}
Nathan Long
źródło
2
I pójść o krok dalej i zastosowanie: is_potential_elvis_impersonator. (Jest / Has / itp. Przedrostek dla zmiennej boolean ..)
Jake Berger,
@jberger - podoba mi się. Odpowiednio edytując odpowiedź.
Nathan Long
3

Aby uzupełnić kilka komentarzy:

Właściwe stosowanie komentarzy ma na celu zrekompensowanie naszego braku 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. ( Clean Code autor: Robert C. Martin )

BTW: Polecam tę książkę.

CSA
źródło
3

Komentarze nie powinny parafrazować kodu, ale wyjaśniają rzeczy, których nie ma w kodzie (większy obraz, dlaczego, dlaczego nie wybrano alternatywy ...) A twoje przykładowe komentarze są takie: parafraza kodu.

Czasami możesz poczuć, że parafraza jest potrzebna na początku elsegałęzi, ale często jest to znak, że twoja thengałąź jest zbyt duża.

AProgrammer
źródło
2

W twoim przykładzie komentarze prawdopodobnie nie są konieczne. Jak wspomniano Caleb , jeśli kod jest wyraźnie napisany, a zmienne mają nazwy semantyczne, jeśli instrukcje nie wymagają komentarza.

Porównaj swój fragment z tym:

if ($x) {
    func1();
} else {
    func2();
}

W tym przypadku zdecydowanie chciałbyś użyć komentarzy, aby opisać, co reprezentują x, func1 i func2 (i uderzyć osobę, która nazwała rzeczy według tego schematu, zwłaszcza jeśli to ty). Nie możesz nawet powiedzieć, czy $xto ma być wartość logiczna. Ale jest to również przypadek, w którym niekoniecznie potrzebujesz komentarzy, jeśli możesz zmienić fakturę i zmienić nazwę.

Ogólnie lubię pisać komentarze do bloków logicznych, które opisują rzeczy, których sam kod nie potrafi. Jedna linijka co ~ 10-20 linii, która opisuje, co osiąga następująca garść linii na jednym wyższym poziomie abstrakcji (np. W // Make the right amount of magic happentwoim przykładzie) pomoże ci się zorientować i da nowemu recenzentowi wgląd w to, co robisz i kiedy .

Właściwie często piszę te linijki przed rozpoczęciem pisania kodu, aby nie stracić kontroli nad przepływem, jaki powinien mieć ten segment.

Wreszcie, jeśli naprawdę wolisz (lub istnieje mandat, który wymaga) komentowania klauzul w bloku if bez względu na czytelność kodu, polecam:

// Broad description of block
if (something) {
    //Do this because something
    something();
} else {
    //Do this because !something
    somethingElse();
}

Wydaje mi się, że jest najczystszy, ponieważ komentarz jest zgodny z kodem, którego dotyczy. Komentarz opisujący kod powinien być jak najbardziej zbliżony do komentarza, który opisuje.

przedpola
źródło
2
if (IsWeekDay(day))
{// weekday -> alarm at 7am
   ...
}
else if(day == DayOfWeek.Saturday)
{// saturday -> alarm at 11am
   ...
}
else
{// (sunday) -> no alarm
   ...
}

Trzymam wsporniki w jednej linii i układam je zaraz za wspornikiem.

[Condition] -> [pseudo-code]

Z drugiej strony, technicznie oznacza to, że wszystkie inne warunki zawiodły, więc zwykle używam nawiasów.

([Condition]) -> [pseudo-code]

Uwaga: dotyczy C #.

Jake Berger
źródło
1

Staram się używać komentarzy wewnątrz bloku mówiących, co robi ten blok (twoja pierwsza próbka).

Gdzie ten rodzaj się psuje, jest podczas używania elseif. Używam Basic, więc nie ma wyraźnego bloku końcowego i często muszę komentować, co warunek sprawdza, który idzie na powyższej linii (z przerwaniem linii oczywiście), jeśli jest za długi.

'Check XYZ
If Condition1 then
  'We need to do T and S
  DoCodeFor1();

'Check ABC
ElseIf Condition1 then
  'This requires something else to be done
  DoCodeFor2()

Else
  'We have no other option than to...
  DoCodeFor3()

End If
Deanna
źródło
Tak, to naprawdę działa lepiej, gdy używasz języka bez nawiasów.
acme
1
  • Trzymaj bloki warunkowe naprawdę krótkie.
  • Wywołaj metodę o ładnej opisowej nazwie, jeśli wygląda na to, że kod warunkowy będzie czymś więcej niż prostą linią lub dwiema.
  • Użyj ładnych opisowych nazw dla swoich zmiennych.
  • Upewnij się, że wyrażenie warunkowe ma jasne znaczenie i nie jest zaciemnione ani długie. Użyj metody, jeśli pomaga to utrzymać czystość i czytelność.

Jeśli powyższe nie powiedzie się, dodaj bardzo mały opisowy komentarz przed instrukcją if, aby wyjaśnić swoje zamiary. W przeciwnym razie naprawdę nie powinno być potrzeby komentowania.

S.Robins
źródło
0

W C ++ lub C # zazwyczaj nie komentuję prostych przypadków (gdy jest jasne, co się dzieje) i używam tego rodzaju stylu do komentowania końcowego ...

if (pattern == AAA)
{
  DoSomethingAAA();
}
else if (pattern == BBB)
{
  DoSomethingBBB();
}
else // if (pattern == CCC)
{
  DoSomethingCCC();
}
dodgy_coder
źródło
4
Lub lepiej „pattern.doSomething ()” i pozwól OO wykonać swoją pracę.
Paul Tomblin