Каковы примеры комментариев, которые говорят вам, почему вместо того, как или что? [закрыто]

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. Если все приводят действительный пример, то все они являются правильными ответами. Формат этого веб-сайта облегчает процесс вопросов и ответов, когда не все ответы одинаковы.
Дэвид Качиньский
Хороший вопрос, @ Давид-Качиньский. Что ты предлагаешь?
Рик
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; оба проекта пытаются следовать этому правилу.

Я также рекомендую придерживаться этого правила еще более строго в журналах фиксации . Для комментариев кода может случиться так, что вы исправите код, но забудете обновить комментарий. С количеством кода в обычном проекте это гарантированно произойдет рано или поздно. С другой стороны, журнал фиксации привязан к конкретному изменению и может быть вызван с использованием функциональных возможностей «annotate» / «обвинить» системы контроля версий. Снова у Git и Linux есть несколько хороших примеров.

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

  1. Все представленные изменения проверяются, и журнал фиксации - это то, что должно объяснить изменение рецензенту.
  2. При обнаружении ошибки соответствующие журналы извлекаются с использованием «кирки» или «вины», чтобы избежать возврата к ранее некорректному поведению.

(примечание: мне потребовалось не более 10 минут случайного просмотра репозитория git, чтобы придумать эти два примера, так что было бы легко найти больше там)

Ян Худек
источник
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
thegrinner
источник
4
Первый пример чрезмерно многословен и включает в себя большую часть «как». Он должен просто сказать: «Обновите <doodads> из temp <doodad>, чтобы пользователь мог безопасно <foo> использовать его в любое время». Остальное тривиально намекает из того или иного кода. Также «введение в сказку» в первых четырех абзацах последнего примера совершенно бессмысленно. Я бы оставил "Viva La Kludge!"; это смешно, и это в конце. Но начало - слишком много слов, которые нужно выкопать, прежде чем перейти к реальному объяснению.
Ян Худек
@JanHudec Скорректировано в соответствии с вашими отзывами. Смотри правильно?
13
15
Одна из приятных сторон второго примера заключается в том, что он не только объясняет, почему код работает определенным образом, но и объясняет, почему не были приняты другие разумные альтернативы. Это делает код более удобным для обслуживания, поскольку следующий парень, который читает код и думает: «Почему я не могу просто разобрать таблицу маршрутизации?» могу просто прочитать комментарий. Кроме того, кто - то , кто действительно пришел с уважительной причиной , чтобы изменить код будет более уверены , что это безопасно. В противном случае сопровождающий остаётся бояться, что любое изменение потерпит неудачу в (неизвестном) сценарии, который вдохновил kludge.
Брайан
18

Я хотел бы начать свой ответ с цитатой из Джефф Этвуд в своем блоге кодекса Сообщает вам , как, Комментарии Скажите , почему :

лучший вид комментариев - это те, которые вам не нужны

Он также заявляет, что:

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

Я полностью согласен, и в этот момент я должен добавить, что прежде чем я смогу сделать код как можно более простым, я заставляю код работать, а затем начинаю рефакторинг. Поэтому во время первого запуска перед рефакторингом добавление комментариев очень помогает.

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

[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 утверждает, что имеет код, который самоочевиден, но больно ли однострочный комментарий?

Я также считаю, что следующие правила из этого блога очень полезны:

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

Любой, кто должен вернуться в свой собственный код или кто-то другой, или даже старый код, знает, что это может быть головной болью. Поэтому вместо того, чтобы быть ленивым или пытаться быть убер-кодером, не комментируя что-либо или очень мало, почему бы не сделать свой собственный или какой-то плохой урод, который должен поддерживать ваш код, будущей жизнью намного проще, следуя приведенным правилам.

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

Предварительная, четкая и обширная документация является ключевым элементом в создании программного обеспечения, которое может выжить и адаптироваться. Документирование в соответствии с высокими стандартами сократит время разработки, улучшит работу и улучшит итоги. Трудно просить больше, чем у любой техники.

Бен Макдугалл
источник
8
Во втором вашем примере можно полностью исключить комментарии путем рефакторинга: actualDayFuture = padIfSingleDigitDate (actualDayFuture); Это тривиально, но более надежный пример выиграл бы от этого подхода.
Крис Кадмор
4
Я бы тоже перенес условное в метод. - Опять же, не для чего-то такого тривиального, но это позволяет мне вообще не думать о логике заполнения. Я бы не стал заменять ваш оригинальный пример, так как это лучший ответ на вопрос. Это скорее дополнительная заметка, исследующая другие альтернативы.
Крис Кадмор
1
Объявление «Конечно, xp утверждает, что у него есть код, который объясняет сам себя, но причиняет ли однострочный комментарий вред?»: Комментарии хороши, но есть и опасность чрезмерного комментирования. Каждая строка комментария может быть забыта для обновления при изменении кода.
Ян Худек
1
Лучший способ сказать это: «Лучший вид комментариев - это отсутствие необходимости в комментариях». Комментарии, которые не нужны (но все равно пишутся), не являются хорошими комментариями.
Каз
1
Интересно, что указанный код int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;содержит ошибку. Конечно, должно быть ... (x < oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;. Хорошие идеи комментариев - плохой код.
Чукс
8

Я склонен сводить комментарии либо к ссылкам, где определенная функциональность / код объясняется более подробно, либо к объяснению, почему выбран определенный способ программирования.

Учитывая, что другие программисты со схожими навыками используют или читают ваш код, важно прокомментировать, если вы используете другой способ достижения чего-либо. Таким образом, вы можете объяснить в комментарии, почему вы выбрали этот путь.

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

Таким образом, «почему» должно дать обоснование вашего выбора.

Roalt
источник
5
Ссылки являются отличным примером. // Этот метод использует алгоритм furshclingeheimer для повторной проверки foobit. Смотрите http: // ...
Крис Кадмор
8

Комментарии должны указывать на то, что код не делает, не обязательно разделять на WHY , HOW или WHAT . Если у вас хорошие имена и хорошо разграниченные функции, вполне возможно, что код точно скажет вам, что происходит. Например:

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)
    {
        ...
    }
    ...
}

Возможно, было бы лучше сказать, почему в первую очередь случайный объект не создается внутри параллельного цикла. Если нет причин, это также может заставить кого-то прийти и понять, что вся идея глупа и является хорошим местом для рефакторинга.

Chewy Gumball
источник
Разумно ли описывать код как не нуждающийся в комментариях, когда комментариям предшествует, WriteTextа не //?
1
Как я сказал в ответе, комментарии не нужны, даже если там не было операторов печати, однако я отредактировал его, чтобы удалить операторы печати, чтобы прояснить ситуацию.
Chewy Gumball
5

Может быть полезно распознать различные виды «почему», в частности:

  • Причины, по которым код, который кажется слишком сложным, не будут работать, если его упростить (например, может показаться, что для обеспечения правильной работы кода в некоторых случаях может потребоваться избыточное приведение типа)

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

Во многих случаях комментарий второго типа в одной части кода может «совпадать» с комментарием первого типа в другом (например, «хотя может показаться, что эта последовательность операций может быть упрощена, подпрограмма Фитца опирается на Wongle не будет Woozled до тех пор, пока Bandersnatch не был Blarped. ")

Supercat
источник
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
Цитирую ОП: «Итак, вернемся к вопросу: если комментарии должны сказать вам, ПОЧЕМУ, что это за ПОЧЕМУ мы говорим?», И я ответил на этот вопрос: ПОЧЕМУ, о чем идет речь, является причиной существования данный кусок кода.
Юха Унтинен,
1
Вопрос специально просит примеры пару раз. Не могли бы вы добавить пример к этому ответу, чтобы сделать его более полезным?
Брайан Оукли
1
Я не думаю, что любой из этих комментариев на самом деле полезен. Если подпись вашей функции была critters.dance(), тогда комментарий просто повторяет очевидное, и «Мы не могли заставить его работать любым другим способом, который мы пробовали», совершенно бесполезно. Кроме того, высказывание «мы будем вызывать метод для каждого объекта» повторяет то, что код очень четко говорит.
Восстановите Монику
1

Я научился ВСЕГДА писать комментарии в заголовочных файлах C ++ (поскольку не всегда понятно, ЧТО делает функция, даже если имя дает хороший совет), особенно если вы передаете API другим разработчикам или используете инструмент для autodoc, такой как doxygen.

Так что для меня типичный комментарий выглядит примерно так

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

Единственный раз, когда я использовал комментарии ПОЧЕМУ, это вещи, которые трудно понять, а иногда даже программисту, например, «НЕ ПРИКАСАЙТЕСЬ К ЭТОМУ!

Обходы, хаки и странное поведение соответствуют критериям WHY в моих глазах ...

Очень хороший и даже веселый пример - это «обходной путь» для некоторого испорченного кода, написанного кем-то по имени Ричард, кто-то другой обернул его и объяснил, почему в комментариях ... https://stackoverflow.com/a/184673/979785

К сожалению, есть довольно много случаев, когда вы вынуждены обернуть быка ****, потому что вы не можете прикоснуться к оригиналу, либо потому, что «так было всегда», либо у вас нет доступа, либо ... ну, вы не хватает времени, чтобы починить оригинал с той целью, которая на самом деле не соответствует накладным расходам.

Кто-то еще
источник
7
За исключением того, что вопрос касается комментариев , а не документации . На самом деле это разные вещи ( documentationтег вызывает сожаление, но все же не относится к вопросу).
Томас
Хорошо, извините за то, что в моем родном языке комментарии и комментарии к документации взаимозаменяемы, и поэтому с тэгом я предположил, что он применим и для этого вопроса. Это действительно причина, чтобы понизить голос?
AnyOneElse
2
Вопрос пару раз спрашивает о причинах комментариев, но единственный пример, который вы включаете, это какой комментарий. Люди, просматривающие ответы за примеры, могут быть введены в заблуждение вашим примером. Можете ли вы привести пример почему ?
Брайан Оукли
хотя я сказал, что в моем коде очень мало WHY, и я назвал два примера: EDITED ... вот ссылка, которая определенно соответствует WHY
AnyOneElse
@AnyOneElse Я не понизил. Это было там до моего приезда.
Томас
0

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

Цель кодера - другое дело. В простом, понятном и понятном коде цель очевидна. Любой достаточно опытный человек-читатель придет к цели блока кода, просто прочитав код. Большая часть кода должна читаться следующим образом.

Иногда связь между намерением и планом неясна. Код показывает, что и как, но не почему. Вот когда комментарии, раскрывающие намерения, стоят того. Цель программиста - почему.

Уолтер Митти
источник
3
Вопрос пару раз задает примеры. Можете ли вы добавить пример к своему ответу, чтобы сделать его более полезным?
Брайан Оукли
0

Имея эту проблему прямо сейчас, мы рассмотрим хранимые процедуры и представления относительно сложной и несколько запутанной модели данных.

Мы (многочисленные) составили выборки типа «Случай, когда x.account не равен нулю и x.address in (выберите адрес из fedex), затем x.account иначе y.account end» повсюду, и производительность ожидается, хотя времени нет все, чтобы прочитать весь исходный код. И этот пример вроде как имеет смысл, но он все еще непостижим.

Комментарии, объясняющие, почему, если в fedex тогда x, а если нет, то y - проливает свет на всю систему, и когда мы читаем достаточно их, мы начинаем понимать это. И это слишком упрощенно, и есть сотни или тысячи подобных утверждений. Мое сердце горячо пылает по отношению к тому, кем был добрый разработчик из 2007 года, кто вставил те, почему.

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

naftalimich
источник
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)
    ...

Как вы, вероятно, можете догадаться, оператор «больше» был больше или равен. Комментарий объясняет, почему старое значение имеет смысл и почему новое значение лучше. Если кто-нибудь посмотрит на это в будущем, он увидит, что использование «>» - это не упущение, а оптимизация. Затем они могут изменить его или оставить, исходя из необходимости в то время.


источник