Иногда алгоритм может быть написан двумя способами:
- Короткий, причудливый путь; или
- Более длинный и понятный способ.
Например, здесь больше, проще способ копирования строки source
в dest
в C:
*dest = *source;
while (*source != '\0') {
source++;
dest++;
*dest = *source;
} (true);
И вот короткий, причудливый путь.
// Copy string source to dest
while (*dest++ = *source++);
Я всегда слышал и читал, что нужно избегать причудливого кода, и я склонен согласиться. Но что, если мы примем во внимание комментарии? Предположим, что, как и в приведенных выше примерах, у нас есть некомментированный, более длинный и, предположительно, более легкий для понимания код и хорошо прокомментированный, короткий, причудливый код? Не причудливый код все еще предпочтителен?
РЕДАКТИРОВАТЬ: Многие прокомментировали имена переменных, поэтому я изменил пример кода, чтобы не делать этого фактора при предпочтении над другими. Я попытался удалить двойное назначение в первом примере, но это только сделало код менее читабельным.
Возможно, это был не лучший пример, потому что многие находят «причудливый» код более читабельным и понятным, чем более длинный код. Идея заключалась в том, чтобы иметь один более длинный код, который был бы намного легче понять, чем очень короткий, но сложный код.
EDIT2: вот новый пример, который я получил от SO :
Комментированная модная версия:
//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );
Длинная версия без комментариев:
int Sum = 0;
for (int i = 1; i < N; ++i)
{
Sum ^= i; //or Sum = Sum ^ i;
}
Ответы:
Как правило, я бы предпочел извлечь необычный код из его собственного метода.
Вместо того, чтобы комментировать причудливый код, его имя метода должно быть всем, что нужно, чтобы прояснить ситуацию.
источник
Я все за более длинную версию. Проблема с короткой версией кода, кроме того, что некоторым программистам труднее ее читать, состоит в том, что большую часть времени труднее обнаружить ошибки, просто взглянув на нее.
У меня есть пример из реальной жизни. В нашем продукте был следующий фрагмент кода:
На первый взгляд этот код выглядит вполне разумным, но после длительного периода времени этот счетчик переполняется и нарушает условие (в реальном сценарии мы разрушили производственную систему нашего клиента с помощью OOM). Этот код немного менее "сложен", но ясно, что он делает то, что должен:
И вы можете сказать, что разработчик, который написал этот код, просто не был достаточно хорош (что не соответствует действительности, он был довольно умным парнем), но я думаю, что если ваша техника кодирования требует, чтобы вы были опытным программистом GOD в Чтобы ваш код был правильным, вы делаете что-то не так. Ваш код должен быть как можно более надежным для вас и для тех, кто должен поддерживать этот код после вас (кто может быть не таким умным, как вы).
Так что - я за простоту и понятность.
Редактировать: Да, а что касается комментариев - это не имеет значения. Многие люди не будут читать комментарии в любом случае ( http://www.javaspecialists.co.za/archive/Issue039.html ), а те, кто не поймет ваш код без комментариев, не поймут его достаточно хорошо с ними, чтобы они может поддерживать это. Цель состоит в том, чтобы помочь людям увидеть, что определенный код является «правильным», комментарии не могут помочь с этим.
источник
Я бы вообще предпочел более длинную версию. На ум приходят две основные причины:
Для лучшего из обоих миров, оберните код в функцию, чье имя делает комментарии для вас:
Единственная причина этого не делать, если производительность была проблемой, а профилирование действительно показало значительную нагрузку на функцию.
источник
Что бы ни было яснее. Часто это компактный, легкий для понимания фрагмент кода, который не требует комментариев ... как ваш второй пример.
Как правило, более короткие фрагменты кода легче понять, так как читателю все время остается в голове. Очевидно, есть предел, когда код становится чрезмерно запутанным, и я не имею в виду, что пробел, улучшающий ясность, должен быть обрезан.
Комментарии никогда не должны содержать ничего очевидного из кода, который просто заставляет читателя читать одно и то же дважды. Для меня первый фрагмент требует уточнения. Почему разработчик не использовал
do...while
цикл для удаления дублирующегося*s = *t;
назначения? Мне нужно разобрать больше кода, чтобы понять, что он реализует копию строки. Комментарий был бы более полезен для этого более длинного кода, чем для более короткого кода.Комментарий ко второму фрагменту почти избыточен, поскольку цикл while практически идиоматичен, но он говорит о том, что код делает на более высоком уровне, чем сам код, что делает его полезным комментарием.
источник
do ... while
просто потому, что я не думал об этом, когда писал вопрос. Спасибо что подметил это. ^^ Второй фрагмент может быть очевиден для вас, но это, конечно, не для меня.Проблема в том, что нет четкого определения,
short fancy code
поскольку оно очень сильно зависит от уровня программиста. В то время как у некоторых людей нет проблем с пониманиемwhile(*s++ = *t++);
выражения, другие будут.Лично я нахожу
while(*s++ = *t++);
отлично читаемым и длиннее, труднее для чтения. Другие могут не согласиться, хотя.Независимо от этого, это просто вопрос использования здравого смысла. Читаемость должна определенно быть приоритетом, но есть момент, когда длинный код становится менее читаемым, когда становится длиннее. Многословие часто снижает читабельность из моего опыта.
источник
Я должен не согласиться с большинством других ответов здесь - я думаю (по крайней мере, в этом случае), чем короче код, тем лучше. Вопреки вашему требованию, более длинный код не «проще», по крайней мере, для читателя. Во всяком случае, вы, кажется, перестали стремиться сделать его длиннее, хотя это затрудняет понимание кода и / или гарантирует правильную работу.
В частности, наличие назначения первого байта строки вне цикла, отдельного от назначения для других байтов, означает, что нужно быть намного более осторожным при чтении, чтобы быть уверенным, что все байты скопированы правильно. Основная последовательность действий в более короткой версии намного легче проверить. Его единственная реальная проблема заключается в форматировании - когда у вас намеренно пустое тело цикла, лучше прояснить это, что-то вроде:
или даже:
Некоторые люди предпочитают использовать вместо этого фигурные скобки:
Независимо от того, какое форматирование вы предпочитаете, достаточно ошибок было сделано с такими вещами, как:
... важно быть уверенным, что 1) очевидно, что на самом деле контролируется каким-либо контролем потока, и 2) очевидно, что код был написан, зная, что им контролируется, поэтому кто-то, читая его, не тратит время на попытки чтобы выяснить, нашли ли они только что ошибку.
источник
Убедитесь, что любой другой программист может понять, что делает ваш код - и даже лучше, если он выглядит с первого взгляда (здесь хорошие имена и комментарии вступают в свои права).
Фантастическое кунг-фу и встроенная сборка - все это прекрасно во имя (возможно, ненужного и преждевременного) оптимизации, но даже когда вы не можете понять код, который вы написали, когда вы столкнулись с ошибкой в нем два месяца спустя ... . Какой был смысл? Вы будете стоить себе времени и усилий.
Я часто обращаюсь к дзен Python в таких ситуациях. Особенно:
источник
Не пишите причудливый код в производственном программном обеспечении. Я знаю, что это здорово, когда я могу написать это, и это короче. Написание причудливого кода значительно увеличивает значение «WTF / минута», другими словами, снижает качество.
источник
Это, конечно, полностью зависит от обстоятельств. но в целом я считаю, что это хорошее правило:
~ Брайан Керниган
источник
По моему опыту, самая большая победа с точки зрения короткого причудливого кода - это использование рекурсии, а не итерации. Это также одна из самых сложных вещей, которую нужно понять с первого взгляда на код, если только вы не работаете на языке, где все равно рекурсивно. Я бы все же одобрил его за элегантность и скорость разработки, которую он предлагает, но я стараюсь, чтобы в нем содержались подробные комментарии, если он будет выглядеть непрозрачным для будущих сопровождающих или моей будущей личности.
источник
Я начинаю никогда не доверять комментариям. Слишком часто комментарии не обновляются, когда код обновляется, и сильно устарели или представляют правила от клиентов / руководства, которые больше не актуальны.
Дошло до того, что в некоторых случаях комментарии даже не соответствуют коду, который они описывают.
Если мне придется выбирать между короткой / фантазией и больше / легче понять то я всегда выбираю последний , если не является действительно хорошей причиной.
источник
Читаемость и ремонтопригодность являются ключевыми, и ваш второй пример (то есть более длинный) гораздо больше обоих. Но зачем ограничивать себя двумя вариантами? Даже более длинный код слишком сложен (ИМХО), чтобы не записывать дальше. Я бы поместил его в собственный метод с соответствующим Javadoc (или любым другим) и подходящим именем метода.
источник