Наведіть приклади коментарів, які розповідають, чому замість того, як чи що? [зачинено]


78

Перш за все, у цьому питанні я хотів би триматися осторонь полеміки щодо того, добре чи погано коментує джерело. Я просто намагаюся зрозуміти більш чітко, що означають люди, коли вони говорять про коментарі, які говорять ЧОМУ, ЩО чи ЯК.

Ми часто бачимо вказівки на кшталт "Коментарі повинні говорити, ЧОМУ; сам код повинен говорити вам ЯК". Легко погодитися з твердженням на абстрактному рівні. Однак люди зазвичай кидають це, як догма, і залишають кімнату без додаткових пояснень. Я бачив, як це використовується в дуже багатьох місцях і контекстах, схоже, що люди можуть погодитися на фразу, але вони, схоже, цілком говорять про різні речі.

Отже, повернемося до питання: якщо коментарі повинні сказати вам ЧОМУ, про що це ми говоримо? Чи це причина того, що цей фрагмент коду існує в першу чергу? Це те, що повинен робити цей фрагмент коду? Я був би дуже вдячний, якщо хтось міг би дати чітке пояснення, а потім додати кілька хороших прикладів (погані приклади насправді не потрібні, але випав на свободу, щоб додати їх для контрасту).

Є багато запитань щодо того, хороші чи погані коментарі, але жоден, хто не стосується конкретного питання про те, які є хороші приклади коментарів, які відповідають вам ЧОМУ.


36
Іноді найкращі коментарі адресують ЧОМУ НЕ. Я колись стикався зі складним бітом коду, який виглядав так, що його можна легко спростити. У коментарі було пояснено, чому це очевидне спрощення не спрацювало в даному конкретному випадку (оскільки оригінальний розробник вже випробував це).
Ден Пішельман

6
There are many questions on whether comments are good or bad, but no one that addresses the specific question of what are good examples of comments that tell you WHY. Якщо кожен наводить вагомий приклад, то всі вони правильні відповіді. Формат цього веб-сайту полягає у полегшенні процесу запиту та відповіді, коли не всі відповіді створюються однаковими.
Давид Качинський

Хороший момент, @ david-kaczynski. Що ти пропонуєш?
рик

1
Вгорі голови я не можу придумати спосіб сформулювати питання, щоб єдиний приклад чи узагальнена тактика могли бути найкращою відповіддю. Є частина чату p.se: chat.stackexchange.com/rooms/21/the-whiteboard , але, мабуть, там буде кращий форум для вашого питання, як є. Чесно кажучи, схоже, що ваше запитання отримує тут позитивну відповідь від громади, тому хвилюватися, напевно, не варто. Найкраща порада, яку я можу дати для пошуку прикладів корисних коментарів, - це перегляд популярних публічних сховищ git.
Давид Качинський

Відповіді:


62

Найпоширеніший і найвизначніший приклад - коментарі в різних обхідних шляхах. Наприклад цей:

https://github.com/git/git/blob/master/compat/fopen.c :

/*
 *  The order of the following two lines is important.
 *
 *  FREAD_READS_DIRECTORIES is undefined before including git-compat-util.h
 *  to avoid the redefinition of fopen within git-compat-util.h. This is
 *  necessary since fopen is a macro on some platforms which may be set
 *  based on compiler options. For example, on AIX fopen is set to fopen64
 *  when _LARGE_FILES is defined. The previous technique of merely undefining
 *  fopen after including git-compat-util.h is inadequate in this case.
 */
#undef FREAD_READS_DIRECTORIES
#include "../git-compat-util.h"

Ви обов'язково знайдете більше прикладів у джерелах Git та Linux; обидва проекти намагаються дотримуватися цього правила.

Я також рекомендую дотримуватись цього правила ще більш суворо з використанням журналів фіксації . Для коментарів до коду може трапитися код, але забудьте оновити коментар. Коли кількість коду у звичайному проекті, це гарантовано станеться рано чи пізно. З іншого боку, журнал фіксації прив’язаний до конкретної зміни і може бути відкликаний за допомогою функцій "анотування" / "звинувачення" системи управління версіями. Знову Git та Linux мають кілька хороших прикладів.

Погляньте, наприклад, на цей комітет . (не копіюючи тут, це занадто довго). У ньому є чотири абзаци, що містять майже цілу сторінку (і трохи більше екранного), що описує, що саме було не так і чому це було неправильно, а потім продовжує та змінює всі колосальні SIX рядки. Вони використовують такі коментарі для двох цілей:

  1. Усі подані зміни переглядаються, і журнал фіксації - це те, що повинно пояснити зміни рецензентові.
  2. Коли помилка знайдена, відповідні журнали витягуються за допомогою "pickaxe" або "blame", щоб уникнути повернення до раніше також неправильної поведінки.

(зауважте: мені знадобилося щонайбільше 10 хвилин випадкового перегляду git repo, щоб придумати ці два приклади, тому було б точно знайти там більше)


29

Коментар, який розповідає, чому пояснюється міркування коду - наприклад:

// We need to sync the values if the temp <doodad> GUID matches one of the active <doodad>'s
// GUID, as the temp <doodad> has the most recent values according to the server and said 
// values might have changed since we added the <doodad>. We want a user to be able to <foo> 
// the <doodad> whenever, which means those values must be accurate.
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

Коментар, який розповідає, як пояснює, що робить код.

// Loop through our <doodads> and check for a GUID match. If it matches, copy the new values
// on the <doodad> that matches 
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

Різниця полягає в тому, що обслуговуючий персонал може подивитися на перший і сказати: "О, значить, це може бути застарілим!" У другому випадку зазначений утримувач має коментар, який нічого не говорить вам, що сам код не виявляє (якщо вважати хороші імена змінних).

Ось приклад із реального життя з приводу коментаря, з якого коду iOS я працював над тим, де нам потрібно було отримати адресу шлюзу (або розумну здогадку для цього). Я міг би просто залишити коментарі, які говорили про такі речі, як "Ініціалізувати приймальний сокет", але це могло б лише сказати технічному обслуговувачу (або майбутньому мені), що відбувається, а не чому мені довелося робити цю дивну хитрості, щоб отримати адресу шлюзу в першість.

/*
 We're going to do something really hacky here and use a custom partial
 implementation of traceroute to get our gateway IP address.

 [rant removed - irrelevant to the point]

 There's no good way to get at the gateway address of an iDevice
 right now. So, we have two options (per https://devforums.apple.com/message/644915#644915 ):
 1. Get at and parse the routing table (like netstat -rn, or route -n)
 2. Do a traceroute and grab the IP address for the first hop

 As far as I can tell, the former requires <sys/route.h> from the Mac OS X
 header files, which doesn't seem like a good idea to me. Also, there's a
 thread on the Apple Developer forums that seems to imply that header isn't
 in iOS for a reason (https://devforums.apple.com/message/774731#774731 ).

 So when we send our request with a TTL of one it will survive a single hop
 to the router and return, triumphant, with the router's IP address!

 Viva la kludge!

 PS: Original source was the below SO question, but I've modded it since then.
 http://stackoverflow.com/questions/14304581/hops-tracing-ttl-reciveform-on-ios/14304923#14304923
 */

// Default to using Google's DNS address. We used to try checking www.google.com
// if reachability reported we had internet, but that could still hang on routers
// that had no internet connectivity - not sure why.
const char *ip_addr = [kGoogleDNS UTF8String]; // Must be const to avoid undefined behavior
struct sockaddr_in destination,fromAddr;
int recv_sock;
int send_sock;

// ... more code follows

4
Перший приклад є надмірно багатослівним і включає більшу частину "як". Слід сказати просто "Оновіть <doodads> від temp <doodad>, щоб користувач міг безпечно <foo> це коли завгодно." Решта - це банально - це означає або з коду. Також "вступ до казки" у перших чотирьох абзацах останнього прикладу абсолютно безглуздий. Я залишив би "Viva la kludge!"; це смішно, і це врешті-решт. Але початок - це занадто багато слів, які треба перекопати, перш ніж дійти до власне пояснення.
Ян Худек

@JanHudec Коригується відповідно до ваших відгуків. Подивіться, чи не так?
thegrinner

15
Одна з приємних речей у другому прикладі полягає в тому, що він не тільки пояснює, чому код працює певним чином, але й пояснює, чому інші, розумні альтернативи не були прийняті. Це робить код набагато більш реальним, оскільки наступний хлопець, який читає код і думає: "Чому я не можу просто проаналізувати таблицю маршрутизації?" можна просто прочитати коментар. Крім того, хто - то , хто дійсно прийшов з поважною причиною , щоб змінити код буде більш впевнені , що це безпечно. В іншому випадку, утримувач може побоюватися, що будь-які зміни не вдасться (невідомий) сценарій, який надихнув хизу.
Брайан

18

Я б хотів розпочати свою відповідь цитатою, яку зробив Джефф Етвуд у своєму дописі в блозі Код розповідає вам як, коментарі .

найкращий вид коментарів - це ті, які вам не потрібні

Він також заявляє, що:

Спершу слід прагнути, щоб ваш код був максимально простим для розуміння, не покладаючись на коментарі як на милицю. Тільки в тому випадку, коли код не може бути простішим для розуміння, якщо ви почнете додавати коментарі.

Я повністю погоджуюся, і на цьому етапі я повинен додати, що перш ніж я можу почати робити код якомога простішим, я змушую код працювати, а потім починаю рефакторинг. Тому під час першого запуску перед рефакторингом додайте, чому коментарі допомагають дуже багато.

Наприклад, якщо використовувати три вкладені петлі з двовимірними хеш-таблицями для заповнення таблиці буднів під час розбору даних, дуже легко втратити слідку про те, що хтось чи навіть власноруч зробив, якщо його не дивилися кілька тижнів і раптом рефакторингу.

[loop1]6oclock -> [loop2]Monday -> [loop3]stage 1 to 4
         -> tuesday-> stage 1 to 4
         ...
         -> Saturday -> stage 1 to 4
    7oclock -> Monday-> stage 1 to 4
        ....etc.

Верхня частина - приклад того, як працюватимуть 3 вкладені петлі перед рефакторингом.
Також пояснення деяких галузевих умов може допомогти зрозуміти код набагато краще з тим, що хтось думав у процесі:

// added a zero before the actual day in order for the days always to be 2 digits long.
if( actualDayFuture < 10 ) 
{ 
     actualDayFuture = padIfSingleDigitDate(actualDayFuture); 
}

Навіть простий і очевидний код добре працює з коментарями. Просто щоб зробити речі трохи більш очевидними, зрозумілішими або простішими для розуміння для колег і навіть для себе в обслуговуванні програмного забезпечення.

Впевнений, що xp заявляє про код, який сам пояснює, але чи коментує один рядок коментар?

Я також вважаю такі правила цього блогу дуже корисними:

  • Розумійте матеріал, перш ніж писати
  • Пишіть так, ніби ваша аудиторія є четвертим класом
  • Подумайте, як читачі можуть вас неправильно трактувати

Кожен, кому доводиться повертатися до власного коду, чи хтось інший чи навіть застарілий код, знає, що це може бути головним болем. Тож замість того, щоб лінуватися чи намагатися стати кодером uber, не коментуючи нічого або дуже мало, чому б вам не зробити власного чи якогось бідного клопотателя, якому доводиться набагато легше підтримувати ваш код, подальше життя, дотримуючись цитованих правил.

Також багато прийнятих рішень щодо програмування сумніваються під час оглядів, і не завжди зрозуміло, чому деякі частини були написані такими, якими вони були, навіть якщо деякі розділи коду є життєво важливими для роботи програми через велику помилку, виявлену, оскільки код використовувався протягом багатьох років . Тож, щоб не нудьгувати всім повністю з tl; dr закрийте з останньою цитатою з acmqueue :

Попередня, чітка та обширна документація є ключовим елементом у створенні програмного забезпечення, яке може вижити та адаптуватися. Документування високих стандартів скоротить час розробки, призведе до кращої роботи та покращить підсумок. Важко попросити більше ніж будь-яку техніку.


8
У вашому другому прикладі ви можете повністю усунути коментарі шляхом рефакторингу: currentDayFuture = padIfSingleDigitDate (фактичноDayFuture); Це банально, але більш надійний приклад виграє від цього підходу.
Кріс Кадмор

4
Я б також переніс умовне в метод. - Знову ж таки, не для чогось такого тривіального, але це дозволяє мені взагалі нехтувати думкою про логіку прокладки. Я б не замінив ваш оригінальний приклад, оскільки це краща відповідь на питання. Це більше бічна примітка, вивчення інших альтернатив.
Кріс Кадмор

1
Оголошення "Впевнений, що xp заявляє про код, який пояснюється самостійно, але болить однорядковий коментар?": Коментарі хороші, але також існує небезпека перекоментувати коментарі. Кожен рядок коментарів - той, який хтось може забути оновити, коли змінює код.
Ян Худек

1
Кращий спосіб сказати це: «Найкращий вид коментаря - відсутність потреби в коментарі». Коментарі, які не потрібні (але все-таки написані) - не гарні коментарі.
Каз

1
Цікаво, що посилається код int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;є помилковим. Безумовно, має бути ... (x < oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;. Хороші ідеї для коментарів - поганий код.
chux

8

Я схильний зводити коментарі до будь-яких посилань, де певна функціональність / код пояснюється більш ретельно, або до пояснення того, чому обраний певний спосіб програмування.

Враховуючи, що інші програмісти, що мають подібні навички, використовують чи читають ваш код, важливо прокоментувати, якщо ви використовуєте спосіб, який не був очікуваний. Тож ви можете пояснити в коментарі, чому ви обираєте саме цей шлях.

Наприклад, якщо ви можете використовувати два різних датчика на пристрої Android, і один з них не відповідає вашим потребам, ви можете пояснити в коментарі, чому ви вибрали другий.

Тож "чому" має обґрунтовувати зроблений вами вибір.


5
Посилання - чудовий приклад. // Цей метод використовує алгоритм furshclingeheimer для ростенізації фобіту. Дивіться http: // ...
Кріс Кадмор

8

У коментарях має бути вказано, що код не робить, не обов'язково розмежовуючи ЧОМУ , ЯК чи ЩО . Якщо у вас є хороші імена та добре розмежовані функції, цілком можливо, що код може точно сказати вам, що відбувається. Наприклад:

List<LightMap> maps = makeLightmaps(receivingModels);
TrianglePartitioner partition = new Octree(castingTriangles);
List<Photon> photons = firePhotons(lights, partition);

if (photons.Count > 0)
{
      PhotonPartitioner photonMap = new KDTree(photons);
      gatherPhotons(maps, photonMap, partition, lights);
}

Цей код дійсно не потребує коментарів. Імена функцій та типів полегшують розуміння.

Однак іноді може бути важко або неможливо реально зробити вільний код, як описано вище. Наприклад, наступний фрагмент коду призначений для пошуку статистично випадкової точки на кулі. Математика досить непрозора, тому коментар із посиланням на пояснення - допомогти сказати, ЯК вона працює. Це може бути зафіксовано у функції, щоб сказати, що це робить, не потребуючи коментарів, якщо потрібно більше одного разу, інакше назва посилання також допомагає в цьому відділі.

double randomA = localGenerator.NextDouble();
double randomB = localGenerator.NextDouble();

//http://mathworld.wolfram.com/SpherePointPicking.html
double theta = 2 * Math.PI * randomA;
double phi = Math.Acos(2 * randomB - 1);

Vector3 randomDirection = new Vector3(Settings.ambientRayLength * (float)(Math.Cos(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)(Math.Sin(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)Math.Cos(phi));

Ще один приклад того, коли коментарі говорять про те, що код не для пояснення рішення. У наступному прикладі код не блокує змінну, яка не є потоковою локальною, всередині різьбового фрагмента коду. Для цього є причина, і коментар пояснює ЧОМУ . Без коментаря це може вважатися помилкою або просто не бути поміченим.

Random random = new Random();
Parallel.For(0, maxPhotons, delegate(int photonIndex, ParallelLoopState state)
{
    ...
    //I don't actually care if this random number is unique between threads, threadsafty is not that big of a deal
    //  in this case and locking the random object could cause a lot of lock contention
    while (random.NextDouble() > reflectProbability)
    {
        ...
    }
    ...
}

Можливо, можна було б покращити сказати, чому випадковий об’єкт не створюється в першу чергу всередині паралельного циклу. Якщо немає причин, це також може змусити когось зійти і зрозуміти, що вся ідея дурна і є хорошим місцем для рефакторингу.


Чи доцільно описати код як такий, що не потребує коментарів, коли коментарям передує, WriteTextа не //?

1
Як я вже говорив у відповіді, коментарі не потрібні, навіть якщо не було заяв про друк, однак я відредагував це, щоб видалити друковані висловлювання, щоб зробити точку зрозумілішою.
Chewy Gumball

5

Можливо, буде корисно розпізнати різні види "чому" - найголовніше:

  • Причини, що код, який видається надмірно складним, не спрацює, якщо його спростити (наприклад, начебто зайвий набір тексту може знадобитися для забезпечення роботи коду в деяких кутових випадках).

  • Причини того, що певна проста операція, яка виглядає небезпечною, насправді є безпечною (наприклад, "Наша програма даних щодо отримання даних буде повідомляти, що елемент манекену минулого останнього є меншим за будь-який інший, а елемент після цього як більший; будь-який предмет, який слід сортувати перед іншим, у послідовній висхідній чи низхідній послідовності, буде щонайменше ще один (можливо, фіктивний) елемент, що слідує за ним ").

У багатьох випадках коментар другого типу в одній частині коду може «збігатися» з коментарем першого типу в іншому (наприклад, «Хоча, здається, цю послідовність операцій можна спростити, порядок Fitz покладається на Wongle не буде Woozled до того моменту, коли Bandersnatch буде збитий. ")


2

Не забувайте, якщо ви пишете програму, ви не просто випадковим чином набираєте речі, це робите, тому що у вас є модель того, що ви хочете , будь то в офіційному документі чи просто в голові. Речі в вашій голові є такими ж реальними, як програмне забезпечення / дані в комп'ютері (і так само, як імовірно, містять помилки).

Хтось, хто читає ваш код, може не мати цієї моделі в голові, тому коментарі можуть слугувати їм, щоб сказати, що це за модель і як код відноситься до неї. Я думаю, що саме це означає "чому". Безумовно, добре зробити сам код якомога зрозумілішим, але це не завжди досить добре. Приклад:

// transform the x,y point location to the nearest hexagonal cell location
ix1 = (int)floor(0.5 + x + y/2);
iy1 = (int)floor(0.5 + y);

Крім того, модель з часом змінюється, і ці зміни повинні бути перенесені в код. Тому коментарі повинні не тільки говорити "чому" щось у коді, але так само важливо, як змінити його у відповідь на очікувані зміни моделі. Приклад:

// to change to square cell locations, remove the "+ y/2" in the above code

Я думаю, що метою коментарів іноді нехтують.


2
Питання задає приклади. Чи можете ви додати приклад, щоб зробити цю відповідь кориснішою?
Брайан Оуклі

2
Перший фрагмент коду виглядає як класичний приклад пояснення мені "що". Не те, що це поганий коментар, але я не думаю, що це відповідає на питання ОП.

@Jon: Якщо коментаря не було, читач може побачити, що відбувається, але не має поняття, чому.
Майк Данлаве

1
@MikeDunlavey: Я не згоден. Я до сих пір не маю уявлення - чому ви хочете найближчого місця розташування комірок з шестикутниками? Яка мета отримати цю локацію? Чи вплине це на що-небудь, якби я видалив ці два рядки?

2

Не всі мої коментарі є типом "чому", але багато хто з них.
Ось приклади з одного вихідного файлу (Delphi):

// For easier access to the custom properties:

function GetPrivate: Integer;   // It's an integer field in the external program so let's treat it like that here

// The below properties depend on the ones above or are calculated fields.
// They are kept up-to-date in the OnEventModified event of the TTSynchronizerStorage
// or in the ClientDataSet.OnCalcFields of the TcxDBSchedulerStorage.DataSource.DataSet
property IsModified       : Boolean   read GetIsModified   write SetIsModified;
property IsCatTT          : Boolean   read GetIsCatTT      write SetIsCatTT;
property IsSynced         : Boolean   read GetIsSynced     write SetIsSynced;

lLeftPos := pos(' - [',ASubject); // Were subject and [shiftnaam:act,project,cust] concatenated with a dash?

// Things that were added behing the ] we will append to the subject:

// In the storage the custom value must also be set for:
Self.SetCustomFieldValueByname(cCustFldIsCatTT,Result);

// When we show the custom fields in a grid, the Getters are not executed,
// because the DevEx code does not know about our class helpers.
// So we have two keep both properties synchronized ourselves:

// lNewMasterEvent was set to usUpdated, overwrite because we added:
if ARepair then
  lNewMasterEvent.CustUpdateStatus := usRecreated

// The source occurrence date may have bee changed. Using GetOriginalDate we can retrieve the original date,
// then use that for creating a target occurrence (and update its date):

lNewTTOccurrence.CustSyncEntryID := cSyncEntryID0;    // Backward compatibility with old sync methode

// Single event became recurring or vice versa; replace entire event

// In contradiction to CopySingleEventToTimeTell, CopyMasterEventToTimeTell does not have a ANewStatus parameter
// because master events are always added.

Зауважте, що (мій) чому коментарі зазвичай передують коду, який збирається це зробити (звідси закінчується двокрапкою).

У мене є зауваження, що пояснюють лише те, що відбувається, наприклад, коли процес має багато кроків, які мають логічну групування (і код не буде відновлено автоматично, щоб показати це автоматично), я прокоментую так:

// Step 1. Initialization

1

Я розумію, ЧОМУ саме тому, що ви робите щось, можливо, дивно чи, можливо, нелогічно, через ці обставини, що вимагають цього зробити. Як можна побачити в самому коді, незалежно від того , як дивно, навіть якщо код не має «сенс». Що , ймовірно , краще за все сказано на початку документації класу / функції. Отже, це додасть вам додавання ЧОМУ , де ви пояснюєте будь-що, що не входить до складу ЯК і ЩО, а також особливі способи, які вам потрібно сприймати через незалежні від вас причини.

Звичайно, це не завжди так, поза землею єдинорогів та веселок ...

ЯК:

foreach($critters as $creature) {
   $creature->dance();
}

ЩО:

/* Dancing creatures v1.0
 * 
 * The purpose of this is to make all your critters do the funky dance.
 */

foreach($critters as $creature) {
  $creature->dance();
}

ЧОМУ:

// We had to store the items in an array of objects because of _____ (reason)
foreach($critters as $creature) {
   $creature->dance();
}

5
як це відповідає на поставлене запитання?
гнат

1
Цитуючи ОП: "Отже, повернімось до питання: якщо коментарі повинні сказати вам ЧОМУ, про що це ЧОМУ ми говоримо?", І я відповів на це питання: ЧОМУ, про що йдеться, є міркуванням існування заданий фрагмент коду.
Juha Untinen

1
Питання спеціально задає приклади кілька разів. Чи можете ви додати приклад до цієї відповіді, щоб зробити її кориснішою?
Брайан Оуклі

1
Я не думаю, що жоден із цих коментарів насправді корисний. Якщо підпис вашої функції був critters.dance(), то коментар просто повторює очевидне, і "Ми не могли змусити його працювати будь-яким іншим способом, який ми спробували" є абсолютно не корисним. Крім того, кажучи, що "ми будемо називати метод для кожного об'єкта", це повторення того, що код дуже чітко говорить.
Брендан Лонг

1

Я навчився ЗАВЖДИ писати коментарі в заголовках файлів C ++ (оскільки не завжди зрозуміло, що функція виконує, хоча ім'я дає хороший натяк), особливо якщо ви передаєте API іншим розробникам або використовуєте інструмент для autodoc, як doxygen.

Тож для мене типовий коментар виглядає приблизно так

/*** Functionname
/*   What happens here
/*  [in] Params
/*  [out] params
/*** 

Єдиний раз, коли я використовував ЧОМУ коментарі - це речі, які важко зрозуміти, а іноді навіть програмісту, як-от "НЕ ТОЧУЙТЕ ЦЬОГО! Тому що ..." або "ПРОГРАМА МОЖЕ КРИШИТЬ, АКО ЛІНІЯ ВИДАЛЕНА ..."

Обхідні шляхи, хакі та дивна поведінка кваліфікуються ЗАЩО в моїх очах критеріїв ...

Дуже хороший і навіть веселий приклад - це "вирішення" для якогось зіпсованого коду, написаного якоюсь людиною на ім'я Річард, хтось інший загорнув його і пояснив, чому в коментарях ... https://stackoverflow.com/a/184673/979785

На жаль, є досить багато разів, де вас змушують обгортати бика ****, тому що ви не можете доторкнутися до оригіналу, або тому, що "це завжди було так", або у вас немає доступу, або ... ну, ви не маєте часу на виправлення оригіналу з метою, що насправді не відповідає вимогам.


7
За винятком того, що питання стосується коментарів , а не документації . Це насправді різні речі ( documentationтег шкодує, але все ще не стосується питання).
Томас

Добре вибачте, що коментар та документація у моїй рідній мові використовуються як взаємозамінні, і тому з тегом я припустив, що він застосований і для цього питання. Це насправді причина зневаги?
AnyOneElse

2
Питання задає пару раз для прикладів тому, чому зауважень, але єдиний приклад включити це те , що коментар. Люди, які скидають відповіді на приклади, можуть бути введені в оману вашим прикладом. Чи можете ви навести приклад того, чому коментар?
Брайан Оуклі

хоча я сказав, що в моєму коді дуже мало ЧОМУ, і я назвав два приклади: ЗМІНЕНО ... ось посилання, яке, безумовно, відповідає ЧОМУ
AnyOneElse

@AnyOneElse Я не подав заявки. Це було там, перш ніж я приїхав.
Томас

0

Кодекс повинен визначати план виконання. Таким чином послідовник програми (або компілятор) може зрозуміти, що робити і як це зробити. Що розбито на етапи, за якими може слідувати послідовник програми. Примітивні кроки - як.

Намір кодера - інша справа. У простому, зрозумілому, прямому коді наміри очевидні. Будь-який досить досвідчений людський читач прийде до наміру блоку коду, просто прочитавши код. Більшість кодів слід читати так.

Іноді взаємозв'язок між наміром і планом незрозумілий. Код розкриває, що і як, але не чому. Ось тоді коментарі, які розкривають наміри, варті. Намір програміста - це чому.


3
Запитання задає кілька разів приклади. Чи можете ви додати приклад до своєї відповіді, щоб зробити її кориснішою?
Брайан Оуклі

0

Наразі ця проблема зараз проходить через збережені процедури та погляди проти складної і дещо перекрученої моделі даних.

У нас (численні) складені елементи вибору типу "Випадок, коли x.account не є нульовим, і x.address (виберіть адресу від fedex), то x.account else y.account end", і продуктивність очікується, хоча часу немає на всі, щоб прочитати весь вихідний код. І цей приклад роду kindof має сенс, але це все-таки непереборно.

У коментарях, що пояснюють, чому якщо у fedex тоді x, а якщо ні, то y - проливає світло на всю систему, і коли ми їх читаємо достатньо, ми починаємо її отримувати. І це закінчилося спрощено, і є сотні або тисячі подібних тверджень. Моє серце гаряче світиться до того, хто був добрим розробником з 2007 року, хто поставив у те, чому.

Тож так, складні моделі з перекрученими даними та волохаті вигляд та збережена процедура з кількома вірно названими шляхами, будь ласка, з любов'ю до Богом скажіть нам, чому.


0

Я щойно написав цей коментар; це конкретний приклад пояснення того, чому рядок коду є тим, що він є, і зокрема, чому я змінив його.

Метод вивчає збережені дані та оцінює, чи є завершеним цей день на одному кінці та через дату початку на іншому.

// In principal, this should be ">=", as we may have data up to the account start
// date but not complete for that day; in practice, 98% of the time if we have
// data for the start date it *is* complete, and requerying it would be a waste
// of time.
while (endDate > accountStartDate)
    ...

Як ви, напевно, здогадуєтесь, оператор з більшими показниками, ніж оператор, був більшим або рівним. У коментарі пояснюється, чому старе значення має сенс і чому нове значення краще. Якщо хтось погляне на це в майбутньому, він побачить, що використання ">" - це не нагляд, а оптимізація. Потім вони можуть змінити його або залишити, виходячи з тогочасних потреб.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.