В какой момент краткость перестает быть добродетелью?

102

Недавнее исправление ошибки требовало от меня просмотра кода, написанного другими членами команды, где я нашел это (это C #):

return (decimal)CostIn > 0 && CostOut > 0 ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 : 0;

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

Я знаю стиль кодирования этого человека по обзору кода, и его подход заключается в том, что чем короче, тем лучше. И, конечно, здесь есть ценность: мы все видели излишне сложные цепочки условной логики, которые можно было бы привести в порядок несколькими удачно расположенными операторами. Но он явно более искусен, чем я, в следующих цепочках операторов, объединенных в одно утверждение.

Это, конечно, в конечном итоге вопрос стиля. Но было ли что-либо написано или исследовано для определения точки, в которой стремление к краткости кода перестает быть полезным и становится барьером для понимания?

Причиной для приведения является Entity Framework. БД должен хранить их как обнуляемые типы. Десятичный? не эквивалентен десятичному в C # и должен быть приведен.

Боб Твей
источник
153
Когда краткость превосходит читабельность.
Роберт Харви
27
Глядя на ваш конкретный пример: приведение - это либо (1) место, где разработчик знает больше, чем компилятор, и ему необходимо сообщить компилятору факт, который не может быть выведен, либо (2) где некоторые данные хранятся в «неправильном» "тип для тех операций, которые нам нужно выполнить над ним. Оба являются сильными индикаторами того, что что-то может быть реорганизовано. Лучшее решение здесь - найти способ написать код без приведения.
Эрик Липперт
29
В частности, кажется странным, что необходимо преобразовать CostIn в десятичное число, чтобы сравнить его с нулем, но не с CostOut; почему это? Что такое тип CostIn, который можно сравнить с нулем только путем преобразования его в десятичную? И почему CostOut не относится к типу CostIn?
Эрик Липперт
12
Более того, логика здесь на самом деле может быть неправильной. Предположим CostOut, равно Double.Epsilon, и, следовательно, больше нуля. Но (decimal)CostOutв этом случае ноль, и у нас есть ошибка деления на ноль. Первый шаг должен состоять в том, чтобы получить правильный код , который я думаю, что это не так. Получите это правильно, сделайте контрольные примеры, и затем сделайте это изящным . Элегантный код и краткий код имеют много общего, но иногда краткость не является душой элегантности.
Эрик Липперт
5
Краткость всегда добродетель. Но наша целевая функция сочетает в себе краткость с другими достоинствами. Если человек может быть короче, не причиняя вреда другим добродетелям, он всегда должен это делать.
Секрет Соломонова

Ответы:

163

Чтобы ответить на ваш вопрос о существующих исследованиях

Но было ли что-либо написано или исследовано для определения точки, в которой стремление к краткости кода перестает быть полезным и становится барьером для понимания?

Да, была работа в этой области.

Чтобы получить представление об этом, вы должны найти способ вычислить метрику, чтобы можно было проводить сравнения на количественной основе (а не просто выполнять сравнение, основанное на остроумии и интуиции, как это делают другие ответы). Одна потенциальная метрика, которая была рассмотрена

Цикломатическая сложность ÷ исходные строки кода ( SLOC )

В вашем примере кода это соотношение очень высокое, потому что все сжато в одну строку.

SATC обнаружил, что наиболее эффективной оценкой является сочетание размера и [цикломатической] сложности. Модули как высокой сложности, так и большого размера, как правило, имеют самую низкую надежность. Модули с небольшим размером и высокой сложностью также представляют риск для надежности, потому что они, как правило, являются очень кратким кодом, который трудно изменить или модифицировать.

Ссылка

Вот несколько ссылок, если вы заинтересованы:

McCabe, T. and A. Watson (1994), Сложность программного обеспечения (CrossTalk: журнал оборонной программной инженерии).

Watson, AH & McCabe, TJ (1996). Структурное тестирование: методология тестирования с использованием метрики цикломатической сложности (специальная публикация NIST 500-235). Получено 14 мая 2011 г. с веб-сайта McCabe Software: http://www.mccabe.com/pdf/mccabe-nist235r.pdf.

Розенберг Л., Хаммер Т., Шоу Дж. (1998). Метрики и надежность программного обеспечения (Материалы IEEE International Symposium по разработке программного обеспечения надежности). Получено 14 мая 2011 г. с веб-сайта Университета штата Пенсильвания: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4041&rep=rep1&type=pdf.

Мое мнение и решение

Лично я никогда не ценил краткость, только читабельность. Иногда краткость помогает удобочитаемости, иногда нет. Более важно то, что вы пишете действительно очевидный код (ROC) вместо кода только для записи (WOC).

Просто для забавы, вот как я бы написал это и попросил членов моей команды написать это:

if ((costIn <= 0) || (costOut <= 0)) return 0;
decimal changeAmount = costOut - costIn;
decimal changePercent = changeAmount / costOut * 100;
return changePercent;

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

Джон Ву
источник
4
Мне действительно нравится пункт охраны для случая с нулевым значением. Может быть заслуживает комментария: как стоимость может быть меньше нуля, что это за особый случай?
user949300
22
+1. Я бы, наверное, добавил что-то вродеif ((costIn < 0) || (costOut < 0)) throw new Exception("costs must not be negative");
Док Браун
13
@DocBrown: Это хорошее предложение, но я хотел бы рассмотреть вопрос о том, можно ли с помощью теста выполнить исключительный путь кода. Если да, то напишите тестовый пример, который использует этот путь к коду. Если нет, то измените все на Assert.
Эрик Липперт
12
Хотя это все хорошие моменты, я считаю, что суть этого вопроса - стиль кода, а не логика. Мой фрагмент кода представляет собой попытку функциональной эквивалентности с точки зрения черного ящика. Бросок исключения - это не то же самое, что возвращение 0, так что решение не будет функционально эквивалентным.
Джон Ву,
30
«Лично я никогда не ценил краткость, только удобочитаемость. Иногда краткость помогает удобочитаемости, иногда нет». Отличный момент. +1 только за это. Мне тоже нравится ваше кодовое решение.
Wildcard
49

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

В этом конкретном случае приведение decimalповторяется снова и снова; было бы лучше в целом переписать его примерно так:

var decIn = (decimal)CostIn;
var decOut = (decimal)CostOut;
return decIn > 0 && CostOut > 0 ? (decOut - decIn ) / decOut * 100 : 0;
//                  ^ as in the question

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

Мейсон Уилер
источник
1
Я, вероятно, пошел бы дальше и рефакторинг ((decOut - decIn ) / decOut) * 100в другую переменную.
FrustratedWithFormsDesigner
9
Ассемблер был намного понятнее: только одна операция на строку. Doh!
2
@FrustratedWithFormsDesigner Я бы даже пошел дальше и обернул условную проверку в скобки.
Крис Cirefice
1
@FrustratedWithFormsDesigner: Извлечение этого до того, как условное выражение обойдёт проверку деления на ноль ( CostOut > 0), так что вам придется расширить условное выражение в if-условие. Не то, чтобы в этом было что-то не так, но это добавляет больше многословия, чем просто введение локального.
wchargin
1
Честно говоря, кажется, что избавление от забросов похоже на то, что вы выполнили достаточно IMO, если кому-то трудно читать, потому что он не может распознать простое вычисление базовой скорости, это его проблема, а не моя.
Вальфрат
7

Хотя я не могу привести какое-либо конкретное исследование по этому вопросу, я бы сказал, что все эти приведения в вашем коде нарушают принцип «Не повторяйся». Похоже, что ваш код пытается выполнить преобразование costInи costOutв тип Decimal, а затем выполнить некоторые проверки правильности результатов таких преобразований и выполнить дополнительные операции с этими преобразованными значениями, если проверки пройдут. Фактически, ваш код выполняет одну из проверок работоспособности для неконвертированного значения, повышая вероятность того, что costOut может содержать значение, которое больше нуля, но меньше, чем половина наименьшего ненулевого значения, которое Decimalможет представлять. Код был бы намного понятнее, если бы он определял переменные типа Decimalдля хранения преобразованных значений, а затем воздействовал на них.

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

Supercat
источник
(Десятичные) приведения, вероятно, должны удовлетворять некоторым требованиям бизнес-правил. При работе с бухгалтерами иногда приходится прыгать через тупые обручи. Я подумал, что у финансового директора случится сердечный приступ, когда он обнаружил строку «Использовать коррекцию округления налога - 0,01 доллара США», которая была неизбежна, учитывая запрошенную функциональность. (Прилагается: цена после уплаты налогов. Мне нужно вычислить цену до вычета налогов.
Вероятность
@LorenPechtel: Учитывая, что точность Decimalокругления приведения зависит от величины рассматриваемой ценности, мне трудно представить бизнес-правила, которые бы определяли, как на самом деле будут вести себя приведения.
суперкат
1
Хороший вопрос - я забыл детали десятичного типа, потому что у меня никогда не было повода хотеть что-то подобное. Теперь я думаю, что это послушание культу груза правилам бизнеса - в частности, деньги не должны быть плавающей точкой.
Лорен Печтел
1
@LorenPechtel: чтобы прояснить мою последнюю мысль: тип с фиксированной точкой может гарантировать, что x + yy либо переполнится, либо выдаст y. DecimalТипа нет. Значение 1.0d / 3.0 будет иметь больше цифр справа от десятичного числа, чем может поддерживаться при использовании больших чисел. Таким образом, сложение и вычитание того же большего числа приведет к потере точности. Типы с фиксированной запятой могут терять точность при дробном умножении или делении, но не при сложении, вычитании, умножении или делении с остатком (например, 1,00 / 7 - это 0,14 остатка 0,2; 1,00 деление 0,15 - 6 остатка 0,10).
суперкат
1
@ Халк: Да, конечно. Я размышлял, использовать ли x + yy, чтобы получить x, x + yx, чтобы получить y, или x + yxy, и закончил тем, что разбил первые два. Важно то, что типы с фиксированной запятой могут гарантировать, что многие последовательности операций никогда не вызовут необнаруженных ошибок округления любой величины. Если код складывает вещи по-разному, чтобы убедиться, что итоги совпадают (например, сравнивая сумму промежуточных итогов строк с суммой промежуточных итогов столбцов), то, что результаты получаются точно равными, гораздо лучше, чем их вывод "близко".
суперкат
5

Я смотрю на этот код и спрашиваю «как стоимость может быть 0 (или меньше)?». На какой особый случай это указывает? Код должен быть

bool BothCostsAreValidProducts = (CostIn > 0) && (CostOut > 0);
if (!BothCostsAreValidProducts)
  return NO_PROFIT;
else {
   // that calculation here...
}

Я предполагаю, что имена здесь: изменить BothCostsAreValidProductsи NO_PROFITпри необходимости.

user949300
источник
Конечно, затраты могут быть нулевыми (подумайте, что преподносит Рождество). И во времена отрицательных процентных ставок отрицательные затраты также не должны вызывать удивления, и, по крайней мере, код должен быть подготовлен для того, чтобы справиться с этим (и будь то с помощью ошибок)
Хаген фон
Вы на правильном пути.
danny117
Это глупо. if (CostIn <= 0 || CostOut <= 0)совершенно нормально.
Майлз Рут
Гораздо менее читабельно. Имя переменной ужасное (лучше будет BothCostsAreValid. Здесь нет ничего о продуктах). Но даже это ничего не добавляет к удобочитаемости, потому что просто проверяя CostIn, CostOut вполне подойдет. Вы бы ввели дополнительную переменную со значимым именем, если значение проверяемого выражения не очевидно.
gnasher729
5

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

  1. Выполните бизнес-требования с наименьшим объемом работы

  2. Избегайте ошибок

  3. Позвольте нам внести изменения в будущем, которые продолжают выполнять 1 и 2

Это цели. Любой принцип или метод разработки (будь то KISS, YAGNI, TDD, SOLID, доказательства, системы типов, динамическое метапрограммирование и т. Д.) Эффективны только в той мере, в какой они помогают нам достичь этих целей.

Рассматриваемая линия, кажется, упустила из виду конечную цель. Хотя это коротко, это не просто. Он фактически содержит ненужную избыточность, повторяя одну и ту же операцию приведения несколько раз. Повторение кода увеличивает сложность и вероятность ошибок. Смешивание преобразования с фактическим расчетом также затрудняет выполнение кода.

Линия имеет три проблемы: охранники (специальный корпус 0), тип приведения и расчет. Каждая проблема довольно проста, если рассматривать ее отдельно, но поскольку все они смешаны в одном и том же выражении, становится трудно следовать.

Непонятно, почему CostOutне разыгрывается при первом использовании CostIn. Может быть веская причина, но цель не ясна (по крайней мере, не без контекста), что означает, что сопровождающий будет опасаться изменять этот код, потому что могут быть некоторые скрытые предположения. И это анафема к ремонтопригодности.

Поскольку CostInвыполняется приведение до сравнения с 0, я предполагаю, что это значение с плавающей запятой. (Если бы это был int, не было бы никакой причины бросать). Но если CostOutэто число с плавающей запятой, тогда код может скрывать скрытую ошибку деления на ноль, поскольку значение с плавающей запятой может быть небольшим, но не нулевым, а нулевым при приведении к десятичному числу (по крайней мере, я считаю, что это возможно).

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

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

JacquesB
источник
1
Важный момент: приведение CostIn один раз вместо двух делает его нечитаемым, потому что читатель не знает, является ли это тонкой ошибкой с очевидным исправлением, или это сделано намеренно. Ясно, что если я не могу точно сказать, что автор имел в виду под предложением, то оно не читается. Должны быть либо два приведения, либо комментарий, объясняющий, почему первое использование CostIn не требует или не должно иметь приведения.
gnasher729
3

Краткость совсем не добродетель. Читаемость это добродетель.

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

Кроме того, код, который вы разместили, даже не следует правилу краткости. Если бы константа быть объявлено с суффиксом M, большинство ужасных (decimal)слепков можно было бы избежать, так как компилятор будет способствовать оставаясь intв decimal. Я считаю, что человек, которого вы описываете, просто использует краткость в качестве оправдания. Скорее всего не намеренно, но все же.

Agent_L
источник
2

За годы моего опыта я пришел к выводу, что предельная краткость - это время - время доминирует над всем остальным. Это включает как время выполнения - сколько времени занимает выполнение программы, так и время обслуживания - сколько времени требуется для добавления функций или исправления ошибок. (То, как вы уравновешиваете эти два, зависит от того, как часто исполняется рассматриваемый код, а не улучшается - помните, что преждевременная оптимизация по-прежнему является корнем зла .) Краткость кода предназначена для улучшения краткости обоих; более короткий код обычно выполняется быстрее, и, как правило, его легче понять и, следовательно, поддерживать. Если это тоже не сработает, то это чистый минус.

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

decimal dIn = (decimal)CostIn;
decimal dOut = (decimal)CostOut;
return dIn > 0 && CostOut > 0 ? ((dOut - dIn) / dOut) * 100 : 0;

(Изменить: это тот же код, что и другой ответ, так что пошли.)

Я фанат троичного оператора ? :, так что я бы оставил это.

Пол Бринкли
источник
5
Троицы трудно читать, особенно если в возвращаемых значениях есть выражения, выходящие за пределы одного значения или переменной.
Almo
Интересно, это то, что вызывает отрицательные голоса? За исключением того, что я написал, я полностью согласен с Мейсоном Уилером, который в настоящее время набрал 10 голосов. Он тоже оставил троицу. Я не знаю, почему так много людей имеют проблемы ? :- я думаю, что приведенный выше пример достаточно компактен, особенно. по сравнению с if-then-else.
Пол Бринкли
1
На самом деле не уверен. Я не отрицал тебя. Я не люблю троичных, потому что не ясно, что находится по обе стороны :. if-elseчитает по-английски: не могу пропустить, что это значит.
Almo
FWIW Я подозреваю, что вы получаете отрицательные отзывы, потому что это очень похоже на ответ Мэйсона Уилера, но он получил их первым.
Боб Tway
1
Смерть троичного оператора !! (также, смерть для табуляции, ни пробелы, ни любая модель скобок и отступов, кроме Аллмана (на самом деле, Дональд (Tm) написал в Твиттере, что это будут первые три закона, которые он примет 20-го числа)
Моуг
2

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

return ((decimal)CostIn > 0 && CostOut > 0) ?
       100 * ( (decimal)CostOut - (decimal)CostIn ) / (decimal)CostOut:
       0;

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

backpackcoder
источник
4
Причиной для приведения является Entity Framework. БД должен хранить их как обнуляемые типы. Удвоить? не эквивалентен Double в C # и должен быть приведен.
Боб Tway
2
@ MattThrower Вы имеете в виду decimal, верно? double! = decimalесть большая разница.
pinkfloydx33
1
@ pinkfloydx33 да! Печатание на телефоне, в котором задействована только половина мозга :)
Боб Tway
Я должен объяснить своим студентам, что типы данных SQL странным образом отличаются от типов, используемых в языках программирования. Я не смог объяснить им, почему . "Я не знаю!" "Little endian!"
3
Я не нахожу это читабельным вообще.
Almo
1

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

Я бы написал это так:

return (decimal)CostIn > 0 && CostOut > 0 
            ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 
            : 0;

В зависимости от того, является ли тип CostInи типом CostOutс плавающей запятой или целым типом, некоторые из приведений также могут быть ненужными. В отличие от floatи double, интегральные значения неявно повышаются до decimal.

Феликс Домбек
источник
Мне жаль, что за это проголосовали без объяснения причин, но мне кажется, что он идентичен ответу кодов рюкзака за вычетом некоторых его замечаний, поэтому я полагаю, что это было оправдано.
PJTraill
@PJTraill Я, должно быть, пропустил это, это действительно почти идентично. Однако я настоятельно предпочитаю, чтобы операторы были на новых строках, поэтому я оставлю свою версию в силе.
Феликс Домбек
Я согласен с операторами, как я заметил в комментарии к другому ответу - я не заметил, что вы сделали это, как я предпочитаю.
PJTraill
0

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

И если я правильно прочитал код, то он пытается выполнить расчет маржи.

var totalSales = CostOut;
var totalCost = CostIn;
var profit = (decimal)(CostOut - CostIn);
var grossMargin = 0m; //profit expressed as percentage of totalSales

if(profit > 0)
{
    grossMargin = profit/totalSales*100
}
Томас Коэль
источник
3
Вы потеряли деление на ноль, возвращает ноль.
danny117
1
и именно поэтому сложно реорганизовать чужой код, максимально развернутый для краткости, и поэтому полезно иметь дополнительные комментарии, чтобы объяснить, почему и как все это работает
Рудольф Олах
0

Я предполагаю, что CostIn * CostOut являются целыми числами.
Так я бы написал
M (Деньги) - это десятичное число

return CostIn > 0 && CostOut > 0 ? 100M * (CostOut - CostIn) / CostOut : 0M;
папараццо
источник
1
надеясь, что они не оба негативные мысли: p
Вальфрат
2
Делится ли на ноль еще?
danny117
@ danny117 Если краткость дает неправильный ответ, значит, он далеко ушел.
Папараццо
Не хочу обновлять вопрос и делать его активным. 100M и 0M вводят десятичную дробь. Я думаю (CostOut - CostIn) будет выполнен как целочисленная математика, а затем разница будет приведена к десятичной.
Папараццо
0

Код написан для понимания людьми; краткость в этом случае не очень выгодна и увеличивает нагрузку на сопровождающего. Для этой краткости вам необходимо расширить это, либо сделав код более самодокументированным (лучше имена переменных), либо добавив больше комментариев, объясняющих, почему он работает таким образом.

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

Рудольф Олах
источник
1
Это где методы и принципы разработки программного обеспечения вступают в игру.
Нефункциональные
0

Краткость больше не является добродетелью, когда

  • Есть деление без предварительной проверки на ноль.
  • Нет проверки на ноль.
  • Там нет очистки.
  • TRY CATCH против бросает пищевую цепь, где ошибка может быть обработана.
  • Сделаны предположения о порядке выполнения асинхронных задач.
  • Задачи, использующие задержку вместо перепланирования в будущем
  • Ненужный IO используется
  • Не использовать оптимистичные обновления
danny117
источник
Когда нет достаточно длинного ответа.
1
Хорошо, это должен был быть комментарий, а не ответ. Но он новый парень, так что объясни хотя бы; не просто понизить голос и убежать! Добро пожаловать на борт, Дэнни. Я отменил понижающее голосование, но в следующий раз
оставлю
2
Хорошо, я расширил ответ, включив некоторые более сложные вещи, которые я выучил трудным путем и простой способ написания краткого кода.
danny117
Спасибо за привет @Mawg. Я хочу отметить, что проверка на нулевое значение - это то, с чем я сталкиваюсь в кратчайшем коде.
danny117
Я только что отредактировал через Android, и он не попросил описание редактирования. Я добавил оптимистичное обновление (определите измененное и предупредите)
danny117
0

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

Очевидно, что ошибка в коде показывает, что есть другая проблема с Q / A, которая была оплошностью, поэтому факт, что была ошибка, которая не была обнаружена, является поводом для беспокойства.

При работе с нефункциональными требованиями, такими как «читаемость» кода, он должен определяться менеджером по разработке и управляться ведущим разработчиком и уважаться разработчиками для обеспечения правильной реализации.

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

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

hanzolo
источник