Как трябва да се коментира структура if-else?

Да приемем, че имате:

if(condition) {
    i = 1;
} else {
    i = 2;
}

и трябва да поставите коментари, обясняващи if и else блокове. Кой е най-четливият начин да го направите, така че някой лесно да ги вземе на пръв поглед?

Обикновено го правя така:

//check for condition
if(condition) {
    i = 1;
} else {
    //condition isn't met
    i = 2;
}

което не намирам за достатъчно добро, тъй като коментарите са разположени на различни нива, така че с бърз поглед просто ще вземете if коментар, а else коментар ще изглежда като принадлежащ към някаква вътрешна структура.

Поставяйки ги така:

if(condition) {
    //check for condition
    i = 1;
} else {
    //condition isn't met
    i = 2;
}

също не ми изглежда добре, тъй като изглежда, че цялата структура не е коментирана (състоянието може да е голямо и да заема няколко реда).

Нещо такова:

//check for condition
if(condition) {
    i = 1;
//condition isn't met
} else {
    i = 2;
}

би бил може би най-добрият стил от гледна точка на коментарите, но объркващ като структура на кода.

Как коментирате такива блокове?

PS. Не питам за рефакторинг на тези два реда код, а само за стила на кода и форматирането на коментара.


person Community    schedule 13.04.2010    source източник
comment
С целия този текст въпросът е всичко друго, но не и бърз :-)   -  person Nathan Fellman    schedule 13.04.2010
comment
Благодаря, че зададохте този въпрос, и аз винаги съм се чудил за това.   -  person helpermethod    schedule 13.04.2010
comment
Мисля, че това трябва да се отвори отново - Това е въпрос относно стила на кодиране, на който може да се отговори въз основа на опит.   -  person Cookie    schedule 11.04.2014


Отговори (12)


Ако е необходимо да коментирам if else изявления, предпочитам да опиша случая, който е накарал кода да достигне тази точка. Особено в код с висока цикломатична сложност

if (condition) { 
// User is taking a course at college x:
    i = 1;
} else { 
// User is not taking any course at college x:
    i = 2;
}
person Community    schedule 13.04.2010
comment
Това ми харесва... по-специално коментарът в блока else. Вашето условие трябва да е ясно, но в зависимост от дължината и сложността (особено влагането) на кода, значението на else може изобщо да не е очевидно. - person mmc; 21.08.2012
comment
Това няма да работи, ако например искате да поставите коментар за i = 2 също в блока else. Изглежда, че и двете са за i = 2 или и двете са за блок else. - person aandis; 03.05.2015
comment
@aandis Можете да отстъпите коментара, свързан с i = 2;, за да разграничите. Въпреки че смятам, че във всяка реална ситуация коментарът сам по себе си не трябва да оставя съмнение дали се отнася до условието или до първото твърдение. - person Daniel Saner; 06.07.2018
comment
@aandis Или за този случай можете да поставите два коментара, разделени с един ред. Вертикалното пространство не би трябвало да е проблем, тъй като дългите или неясни методи трябва да бъдат преработени в по-малки/по-ясни. - person Guimo; 30.04.2019

Друг вариант е:

if(condition) { //check for condition
    i = 1;
} else { //condition isn't met
    i = 2;
}
person Community    schedule 13.04.2010
comment
това е опцията, която харесвам... освен ако коментарите не са много дълги, значи си прецакан...... разочаровам се и изтривам коментарите, защото изглеждат грозни. - person mpen; 13.04.2010
comment
+1 Най-доброто решение според мен. - person helpermethod; 13.04.2010
comment
Това е което правя. Ако коментарите са дълги, тогава поставете блок за коментари над условното обяснение на всичко. - person drawnonward; 13.04.2010
comment
Обичам всички коментари да започват от една и съща позиция (за предпочитане от най-високо ниво). Като ги има навсякъде, ми е много по-трудно да ги прочета. - person serg; 13.04.2010
comment
За мен проверката за условие не е полезна нито сама по себе си, нито като общ заместител. Коментарите ТРЯБВА да бъдат полезни, а не просто да повтарят кода, оттук и моето предпочитание (подробно по-долу) за коментар, обясняващ какво се опитва да определи условието - person Andrew; 09.09.2012

Трябва да коментирате само ако кодът не е обяснителен. Така че направете if самообяснимо. Като това може би

bool fooIsNotReallyGood = ....;

if(fooIsNotReallyGood) {
...
} else {
...
}
person Community    schedule 13.04.2010
comment
+1 Правя всичко възможно кодът ми да бъде разбираем без коментари - person David Johnstone; 13.04.2010
comment
Благодаря, но въпросът не е за това. - person serg; 13.04.2010
comment
@serg555: Може да не зададете изрично този въпрос, но все пак това е отговорът. Ако сте използвали действителни коментари в примерите си по-горе, веднага ще стане ясно, че зависи изцяло от това за какво се отнася конкретният коментар. Действителен коментар на външно ниво, например, може да обясни, че когато имате инсталирана определена графична карта, възниква грешка, която иначе не е проблем, така че правите нещата по различен начин въз основа на това условие. Един вътрешен коментар може да обясни особено сложен алгоритъм и как той е свързан с този конкретен клон на оператора if. - person Mike Burton; 14.04.2010
comment
Това е добре в един идеален свят на прост код. Въпреки това, ако първият блок е дълъг, може вече да не е толкова ясно за какво се отнася блокът else (също в случай на вложени if). Той също така може да почиства кода на някой друг, който предпочита да не преработва. Това е напълно легитимен въпрос. - person mmc; 21.08.2012
comment
@mmc - това е, което добавих променливата bool. Всички тестове могат да бъдат сведени до една променлива. Ако имате нужда от множество променливи, за да намалите теста, за да подобрите четливостта и така да бъде. Това работи във всички случаи. Ако смятате, че някой код е твърде сложен, тогава трябва да можете да създадете прост израз и това трябва да се направи само веднъж, за да сте сигурни, че бъдещите читатели могат да видят как работи тестът. Също така не мога да си представя част от кода, където не можете да опростите кода. Ако опростяването води до проблеми с производителността - тогава въвеждате сложен код с обилни коментари. - person Preet Sangha; 22.08.2012
comment
Това е полезна техника, но определено не премахва необходимостта от коментари if/else във всички ситуации. - person Jonathan Potter; 24.04.2015

Ако кодът вече не е самодокументиран, тогава бих го структурирал, както следва:

if (someCondition) {
    // If some condition, then do stuff 1.
    doStuff1();
}
else {
    // Else do stuff 2.
    doStuff2();
}

Но отново, няма много смисъл, ако кодът вече се самодокументира. Ако искате да добавите коментари поради някакво сложно условие като:

if (x == null || x.startsWith("foo") || x.endsWith("bar") || x.equals("baz")) {
    doStuff1();
}
else {
    doStuff2();
}

Тогава бих обмислил да го преработя като:

boolean someCondition = (x == null || x.startsWith("foo") || x.endsWith("baz") || x.equals("waa");

if (someCondition) {
    doStuff1();
} else {
    doStuff2();
}

При което името на променливата someCondition всъщност обобщава цялото условие накратко. напр. usernameIsValid, userIsAllowedToLogin или така.

person Community    schedule 13.04.2010
comment
Също така предпочитам коментар над другото на същото ниво раздел. Не съм съгласен да не коментирам кода, операторът if може да е лесен като someCondition, но вътре в неговата структура има например 300 реда и в този случай НЕ коментирането на оператор else би било глупаво, защото трябва да превъртите 300 реда отгоре и друг 300 дъно.. - person s3m3n; 20.04.2013

Изберете условия за самокоментиране, тогава не са необходими допълнителни коментари. Да кажем, че условието е да бъде достигната максималната стойност на заема. Това ни дава:

if (maximumLoanToValueIsReached)
{
   i=1;
}
else
{
   i=2;
}

Няма нужда да се уточнява, когато i=2, че максималният заем към стойност не е достигнат, тъй като това е очевидно. Освен това бих преименувал i на нещо по-смислено.

person Community    schedule 13.04.2010

Коментарите са много лично нещо и (както може да се види от някои от по-ранните отговори) предизвикват толкова дебат, колкото и кодът.

В прости случаи коментарите отклоняват вниманието от кода. Но ако приемем по-сложно условие, предпочитам:

/*
** Comment explaining what the condition
** is trying to determine
*/
if ( condition )
{
    /*
    ** Comment explaining the implications
    ** of the condition being met
    */
    do_something();
}
else
{
    /*
    ** Comment explaining the implications
    ** of the condition not being met
    */
    do_something_else();
}

Във всеки случай коментарите не трябва просто да повтарят кода.

person Community    schedule 21.08.2012

Изобщо не бих коментирал в тези конкретни случаи - коментарите не добавят никаква стойност към вашия вече ясен код. Ако имате наистина сложно условие, което е трудно за четене, бих помислил да го разложа във функция (вероятно inline) със собствено много чисто име.

person Community    schedule 13.04.2010

//condition isn't met изглежда безполезен коментар. Но в случай, че се изисква такъв коментар, аз го правя така (C#):

//check for condition
if(condition) 
{
    i = 1;
} 
//some other condition
else 
{
    i = 2;
}

Въпреки това, ако блокът е само if-else, тогава бих обединил и двата коментара преди if.

За javascript предпочитам

//check for condition
if(condition) {
    i = 1;
} else { //some other condition
    i = 2;
}

P.S. Явно има толкова мнения, колкото и хора :)

person Community    schedule 13.04.2010

Ето как правя моите коментари за операторите if then, въпреки че обикновено намирам, че това не е необходимо. Харесва ми да го поставя в съответствие с if/else и да го поставя на същото място

if ( condition )    //if above the bar
{
    i = 0;
    k = 1;
}
else                //else if below
{
    i = 1;
    k = 2;
}
person Community    schedule 13.04.2010
comment
Харесвам този метод на правене на нещата. Може да заема повече място, но прави абсолютно ясно какво се покрива в оператора за цикъл/if. - person Faken; 13.04.2010

Няма еднозначен отговор – различните хора ще имат различни мнения относно това, което е най- четиво. Мисля обаче, че има съгласие, че коментарите трябва действително да добавят стойност към (иначе разбиращия се) код и че стилът на коментиране трябва да бъде последователен.

Начинът, по който обработвам коментари за условия, които не се разбират веднага, е следният:

  // If the condition for a local tree imbalance is met,
  // juggle the immediate nodes to re-establish the balance.
  // Otherwise, execute a global balancing pass.
  if ( somewhat muddled condition )
  {
     ...code...
  }
  else // Tree is in local balance
  {
     ... more code...

  } // if/else (tree locally imbalanced) 

Коментарът за крайния '}' съществува предимно, за да придаде на края на условието повече визуална тежест, за да улесни четенето през източника.

person Community    schedule 13.04.2010

Променливите са важни, а не самите условия.

if condition: # <condition dependent variable> was <predicated>
  dosomething()
elif othercondition: # <othercondition dependent variable> <predicated>
  dootherthing()
else: # <all variables> <not predicated>
  doelsething()
person Community    schedule 13.04.2010

Можете да извлечете if-else код към методи и да ги наименувате правилно:

function main() {
  checkForCondition(condition);
  conditionIsNotMet(condition);
}

function checkForCondition(boolean condition) {
  if (condition) {
    i = 1;
  }
}

function conditionIsNotMet(boolean condition) {
  if (!condition) {
    i = 2;
  }
}

В такъв тривиален случай това изглежда като прекаляване, но представете си, че имате повече от един ред на клон if-else.

person Community    schedule 13.04.2010
comment
Хаха, в такъв случай не е ли по-добре да направим нещо подобно? if (условие) conditionIsMet(); else conditionIsNotMet(); - person Aoi Karasu; 13.04.2010
comment
Има много проблеми с този код. Първо, връзката или/или между вашите две функции (фактът, че винаги само една от тях ще влезе в сила) е скрита в main(). Трябва да потърсите действителните твърдения на няколко места и не виждайте веднага дали може да има странични ефекти. Освен това проверявате състоянието два пъти, което е потенциално скъпо. И добавя допълнителните разходи за две извиквания на функции, които вероятно също ще искат да върнат нещо обратно към main. — Знам, че отговорът е стар, но си помислих, че няма да навреди да подкрепя по някакъв начин отрицателните гласове. - person Daniel Saner; 06.07.2018