Я зарабатываю программированием с 1979 года, и большую часть этого времени мне приходится работать с чужим кодом. Поначалу было: "Добавьте эту маленькую функцию к тому, что у нас уже есть". Теперь — "как мы можем стать лучше" и " стоит ли сохранять данный код?". Прочтение кода всегда было огромной составляющей в моей работе, и по этой причине для меня очень важно, какой код пишу я (и люди, с которыми работаю). Конечно, хочется, чтобы он был быстрым — в конце концов, я программист на C++. Кроме того, он должен быть корректным. Но есть нечто большее, помимо этих двух вещей: я хочу, чтобы код был читабельным, понятным, разумным и даже приятным.

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

В этой статье я хочу поговорить о факторе «почему» и о людях, которые пишут код, который вы читаете и поддерживаете.

Что такое эмоции?

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

  • Убирайся!

  • Доверься этому человеку.

  • Улыбнись, расслабься, все в порядке.

  • Ругайтесь, орите, бейте и кричите!

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

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

Никаких эмоций не допускается

Люди, считающие, что эмоциональные реакции неуместны, особенно часто встречаются в сфере разработки программного обеспечения. Они блокируют деструктивные внеполосные прерывания, которыми являются эмоции. Настаивают на том, что в спорах нужно побеждать, применяя логику, а не с помощью сильных чувств. Только кристально чистая логика единиц и нулей матрицы. Многие действительно так считают и пытаются подавить эмоции в себе и других.

В определенной степени они правы. Если мы спорим о том, сколько параметров принимает функция, я не хочу слышать, что вы считаете пять правильным числом: "Мне просто нравится, когда это так". Я хочу, чтобы вы убедили меня с помощью логики. Но во многих случаях быстрое общее заключение, которое делается с помощью эмоций, очень полезно - не для победы в споре, а для выполнения моей работы. Я смотрю на API, на целую коллекцию функций, всех их параметров, и что-то во мне говорит: "ФФФУ-У-У-У". Не знаю, в чем именно проблема, но меня тянет взглянуть на нее поближе и разобраться, что с рациональной точки зрения я думаю об этой части кода. Я не собираюсь говорить: "Заплатите мне, чтобы перестроить всю вашу систему, потому что она кажется мне отвратительной и неправильной", но эта первая эмоциональная реакция имела большую ценность, привлекая меня к тому месту, которое требует внимания. Я научилась высоко ценить такие сигналы.

Но не все так делают. Когда я говорю: "Не знаю, что конкретно мне не нравится в этом API на данный момент; с первого взгляда, моя интуиция чувствует проблему, и уверена, что на это нужно обратить внимание, поэтому сегодня во второй половине дня подготовлю вам краткий отчет", они могут отвергнуть это, потому что здесь не о чем будет спорить, они должны просто довериться мне. Они могут не принять такое предложение, посчитав, что я веду себя как-то непонятно или эмоционально, вместо того чтобы использовать свой опыт. (Это странно, потому что эмоциональные и интуитивные реакции на ситуации — это именно то, как ваш опыт обычно проявляет себя). Возможно, они просто имеют привычку говорить другим людям, что не стоит испытывать эмоции: не стоит сильно радоваться чему-то или сильно расстраиваться. У нас есть целый юмористический штамм на этот счет: "Ох, уж эта человечность" и другие мемы, где людей высмеивают за то, что они расстраиваются из-за пустяков или потому, что иногда слишком счастливы.

Эмоциональные и интуитивные реакции на ситуации — это то, как обычно проявляет себя ваш опыт.

Насмехаться над людьми за их "проблемы первого мира" или отвечать "о, человечность..", когда они на взводе, — это наш способ навязать социальную норму в сообществе программистов, особенно в тех из них, которые уходят корнями в 20-й век, а не в 21-й. Социальная норма гласит: "Не демонстрируй мне эмоции", а в идеале — вообще не испытывай эмоций. Но вот в чем дело: программисты — это люди, и у них есть эмоции. Поэтому, нравится вам это или нет, у программистов есть эмоции.

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

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

Ваш код показывает эмоции

На самом деле, код полон эмоций, которые можно прочесть прямо на странице. Большинство может мне не поверить. Позвольте мне показать вам несколько примеров.

Страх

Если задаться вопросом, почему люди поступают так или иначе, можно получить несколько интересных ответов. Возьмем в качестве примера закомментированный код. Вряд ли вы найдете кого-то, кому это нравится. Мы рассуждаем о том, что существует контроль исходных текстов; люди могут делать рабочие заметки и вставлять туда удаленные материалы, чтобы использовать их позже; это только запутывает, когда вы потом перечитываете, мешает поиску, и так далее. Но люди продолжают так делать. Почему? Потому что они боятся. "Я могу сделать что-то не так; это может понадобиться мне позже".

Вот пример из реального кода, найденный в середине длинной функции.

//if (m_nCurrentX != g_nCurrentX
//  || m_nCurrentABC != g_nCurrentABC) {
//}

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

Еще одна разочаровывающая категория комментариев: "не вините меня". Разработчик боится, что другой программист или менеджер не одобрит такое, и поэтому оставляет комментарий, объясняющий, что это не его выбор, а кто-то сказал ему сделать изменение. Например:

limit = InputLimit - 1; //as per Bill

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

Страх также является причиной того, что люди не удаляют переменные, которые они даже не используют. Они оставляют в коде строки, которые вычисляют то, что потом никогда не применяется. Функции, которые никогда не вызываются. Переменные-члены, которые никогда не задаются и не используются. "Как я могу быть уверен, что нам это не понадобится?" — прямо говорит разработчик. Либо они знают, что это им не понадобится, но все равно не тратят время на очистку. У них нет на это времени. Их ждут "неприятности" за недостаточно быстрое выполнение работы, а удаление кода, который "никому не навредит", просто не входит в список приоритетов. Да, возможно, в будущем кто-нибудь слегка затормозится, пытаясь выяснить, что происходит, но сейчас этому разработчику нужно уложиться в срок или попытаться избежать увольнения, и поэтому позади себя он оставляет старый ненужный хлам.

Требуется смелость, чтобы отступить от шаблонов в существующем коде, даже если они неправильные. Почти в каждой кодовой базе C++, с которой встречаюсь, я вижу вещи, подобные следующему примеру:

int c, n;
int r1, r2, r3, r4;
double factor;
double pct1, pct2, pct3, v1, v2, v3, v4, v5;
double d1, d2, d3;

Здесь так много неправильного! Ни одна из этих переменных не инициализируется. Ни одна из них не объявляется рядом с местом, где они используются. А имена! Можно догадаться, что такое factor, но что означает r? Я почти уверена: v означает "значение", а d — "дубль". В этих именах вообще нет никакой информации. Но напуганный разработчик, беспокоящийся о том, что скажут рецензенты, боится, что вносит ошибки в рабочий код, возится с ним и просто добавляет d4 в конец списка, будучи уверенным, что сейчас для него это самое безопасное решение.

Кроме того, мне попадается код, который проверяет условия, которые не нуждаются в этом. Вот пример на C++:

if (pPolicy)
{
delete pPolicy;
}

При удалении нулевого указателя ничего не происходит. Это безобидно. В данной проверке нет необходимости, но мне постоянно приходится сталкиваться с этим. (Если бы указатель был установлен в null после удаления, или что-либо еще было сделано внутри этих фигурных скобок, тогда все было бы нормально, но здесь ничего такого не делается). Мне также, вероятно, интересно, почему вы выполняете ручное управление памятью, но сейчас не обращайте на это внимания и сосредоточьтесь на мышлении человека, который продолжает проверять вещи "на всякий случай", того, кто платит производительностью во время рантайма при каждом запуске приложения, потому что чувствует себя нерешительно и неуверенно. Боится.

Предположим, что в процессе обучения и проведения ревью кода люди узнают, что delete по null указателю — это бесполезное действие. Но что делать, если разработчик переживает, что коллеги подведут его? Они многократно проверяют одни и те же ситуации, потому что не могут быть уверены, что условия всегда выполняются. "Это было в коде коллеги, его могли изменить, не сказав мне". Вот то место, где тщательный набор тестов и их выполнение после каждого изменения может улучшить производительность во время рантайма. Если уверенно писать код, зная, что вы получаете валидные параметры из других частей приложения, подумайте, сколько проверок во время рантайма (убедитесь, что x положительно, а y не превышает лимит, и так далее) можно исключить!

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

Высокомерие и гнев

Раннее здесь демонстрировался фрагмент кода с именами переменных r1 и v2. Когда я спросила разработчика, что они означают, то получила ответ: "Разве вы не достаточно умны, чтобы догадаться об этом?". Если я обращаюсь к людям с просьбой объяснить имена obscure функций, ответы звучат примерно так: "Почему я должен общаться с людьми, которые не в состоянии понять это без объяснений?". Это видно на примере таких заведомо непонятных имен, как f(), foo и bar. Если отбросить мрачный юмор в отношении их происхождения, то foo и bar означают: "У этого нет имени, оно не нуждается в названии, и ваше желание, чтобы наименование появилось, является неправильным". Я думаю, что это ужасная вещь — оставлять после себя нечто в коде, чтобы другие такое потом вычитывали.

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

Иногда такое: "Я лучше, чем кто-либо другой", — побуждает разработчиков использовать неструктурированные циклы, а не что-то из библиотеки, писать свои собственные контейнеры и так далее. Возможно, они столкнулись с проблемой производительности десяток или пару лет назад в одной популярной библиотеке и решили, что они всегда будут лучше, чем авторы. Хотя "это не хвастовство, если вы можете это сделать", немногие разработчики могут действительно превзойти тех, кто сосредоточен на работе с определенной библиотекой круглые сутки. Возможно, они измеряли производительность своего решения, созданного вручную с использованием нестандартных данных, в сравнении с библиотечным решением, а, может и не делали этого… Стоит проверить.

Вы удивитесь (я больше не удивляюсь), как часто встречаются насмешливые комментарии и имена в живом коде. Люди, которые говорят lusers, PEBCAK и RTFM в электронных письмах и Slack, делают это и в своем коде. Они также повторяют это в своих коммитах: April Wensel обнаружила кучу совпадений по запросу "stupid user" в комментариях к коммитам на GitHub. Очевидно, что эти комментарии являются публичными (она их нашла). Как вы думаете, что почувствовали бы пользователи, обнаружив в коммите сообщение, которое содержало бы не что иное, как "Будьте добрее к глупому пользователю", когда узнавали о продукте, который они использовали? И, кстати, этому коммитеру самому нужно постараться "быть добрее", потому что такой комментарий демонстрирует явный недостаток доброжелательности. Steve Miller ищет в исполняемых файлах нецензурные слова: в хакерском ПО их оказалось гораздо больше.

У вредоносных программ больше бранных слов в коде, чем у обычных.

Мне также приходилось видеть имена функций и переменных, от которых веет пренебрежением и презрением к выполняемой работе. Речь не идет о том, что переменную называют "пустышкой". Здесь подразумевается такая вещь, как вставка имени коллеги в функцию, чтобы продемонстрировать ему, что он не прав. Однажды я столкнулась с нечто под названием UndoStevesNonsense(). Только это был не Steve и не ерунда; скорее более грубое выражение несогласия. Очевидно, Стив написал код, в котором выполнялись действия, которых, по мнению этого разработчика, не должно было быть; поэтому, вместо того, чтобы решать проблему совместно или обратиться к руководству, он просто их отменил и назвал функцию соответствующим образом. Опять же, если для вас важна производительность во время рантайма, мысль о том, что один разработчик выполняет шаги A, B и C (занимающие время при каждом запуске), а другой затем все переворачивает и организует их отмену, приводит в ужас. Но сегодня такое действительно происходит в реальности.

Эгоизм

Страх, высокомерие и гнев не объясняют всего плохого кода. Еще одна огромная группа разработчиков — эгоисты. Они не тратят время на очистку, рефакторинг, перегруппировку или переименование по ходу работы. Вы можете услышать, как они спрашивают: "Почему я должен тратить свое время на то, чтобы облегчить вам работу?". Представьте, что вам дали час на то, чтобы что-то исправить. Вы справляетесь за 50 минут. Если потратить 20 минут на приведение в порядок, последующие доработки в этой области займут всего полчаса. Результат уже будет достигнут даже после одной корректировки, а после каждой последующей — еще и сверх того. Но если работа в команде оценивается по каждому исправлению, возможно, кто-то другой сэкономит эти полчаса, в то время как первоначальный разработчик будет наказан за лишние 20 минут. Поэтому неудивительно, что эти 20 минут не востребованы.

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

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

Лень

Конечно, не все программисты эгоисты. Некоторые из них просто не могут утруждать себя. "Неважно; это работает. В основном. У нас есть тестировщики, верно?". Они не используют библиотеки, потому что сопротивляются изучению новшеств или поиску дополнительных способов сделать что-то. Они заняты набором кода. Или копипастом. "Абстракция? По-моему, это похоже на работу!" Когда предлагаешь им добавить тестирование, автоматизацию или скрипты, скорее всего услышишь в ответ: "Если считаешь, что это важно, делай сам". Они не проявляют никакого стремления к качеству кода, пользовательскому опыту, срокам, собственному будущему, успеху компании или целям команды. Просто приходят, набирают текст, не задумываясь, и уходят домой, получив деньги за день, независимо от того, что было сделано. И это видно в коде!

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

Теперь предупреждение. Некоторые команды практикуют кранч. Если вы удерживаете коллектив в режиме "кранч" неопределенное время, то в итоге все начнут вести себя так, что это будет неотличимо от лени. У них буквально не будет времени на то, чтобы узнать, как сделать что-то быстрее. Они живут в страхе перед дедлайном, потому что если срок будет сорван, их уволят, компания рухнет, их навсегда станут ассоциировать с провальным проектом. Они не могут сейчас инвестировать час, чтобы затем выиграть день или неделю. Никто не даст им этот час. Они и так не высыпаются и ведут учет того, чей именно брак оказался неудачным, на информационной доске в общей комнате. Код, который выходит после кранча, редко бывает хорошим. Иногда это не имеет значения. Хорошие команды, если необходимо, возвращаются и наводят порядок после, когда сроки вышли. Когда никто этого не сделал, а артефакты все еще в коде, значит существует ленивый разработчик, которому все сходит с рук, или перегоревший программист, за которым никто не присматривает, или, вероятно, это вечный кранч. Плохой код напрямую указывает на неправильные методы управления.

Почему это важно?

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

Конечно, одно буквенное имя переменной не делает человека психопатом. Иногда назвать переменную i — это правильно. Я вижу эмоции в шаблонных схемах, а не в единичных случаях. И если вы видите паттерн и узнаете о команде и разработчиках, то не будете искать автора кода и говорить: "Вау! Раньше я не знал, насколько ты всегда боишься!". Осознание эмоциональных причин плохого кода может дать вам эмпатию при его чтении и исправлении. Читая старый код, я больше не восклицаю "О чем вы думали?". Теперь я понимаю, что иногда люди испытывали нехватку времени, их контролировали, они получали малоприятные рецензии на код или им не хватало инструментов, которыми мы все пользуемся, и в результате все это привело к созданию такого кода.

Обретая такие познания, я, естественно, предлагаю внести необходимые изменения в команду или на рабочем месте. Это может означать, что конкретному участнику коллектива следует чему-то научиться, или надо скорректировать определенную практику менеджмента. Спросите себя, вызывают ли ваши методы управления проблемы с производительностью во время рантайма? Зачастую так и есть, и осознания этого может быть достаточно, чтобы добиться их изменения. Это также поможет направить ваши усилия на то, чтобы заставить конкретного разработчика писать лучший код. Если они пишут плохой код, так как боятся, что их уволят, если они пропустят срок, или не закрывают достаточно тикетов каждый день, либо получают запросы на изменения после ревью кода, то, очевидно, способ повлиять на то, чтобы они работали лучше, — успокоить по поводу таких страхов. Орать на них, чтобы они повысили качество кода, — значит только усилить их испуг и, скорее всего, по этой причине сделать результат еще хуже. Однако, если кто-то пишет плохой код, потому что он эгоистичен или высокомерен, и не заинтересован в облегчении работы для остальной части команды, он не нуждается в успокоении, скорее, ему нужно напомнить о том, что именно является важным для его работодателя.

Вызывают ли ваши методы управления проблемы с производительностью во время рантайма?

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

Загляни туда, куда хочешь попасть

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

Уверенность

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

После добавления функции, исправления ошибки или другой работы над кодом, найдите время, чтобы привести его в порядок. Вы никогда не будете знать об этом коде больше, нежели сейчас, и теперь самое время зафиксировать эти знания в нем самом. Дайте вещам имена, которые объясняют ход ваших мыслей. Оставляйте комментарии, которые помогут людям пройти через острые грани, если таковые имеются. Это способно выручить вас позже или кого-то еще. Такой код говорит: "Я уверен в своей правоте, позвольте мне это продемонстрировать".

Если вам попадается что-то устаревшее, измените это, используя новые возможности языка. (У вас же есть тесты, верно?) Столкнувшись с чем-то, сделанным вручную, поменяйте это на хорошо известный библиотечный подход. (Опять же, у вас есть тесты. Вы можете это сделать.) Когда вы обнаружите множество имен переменных типа r1, r2, r3, замените их на что-то лучшее. Пусть ваш код скажет: "Я достаточно смел, чтобы отстоять правильное решение".

Скромность

Противоположностью высокомерия является скромность. Осознание того, что вы хороши, не то же самое, чтобы считать себя лучшим во всем. Код, признающий, что очередной его читатель, вероятно, является хорошим разработчиком, заслуживающим разъяснений, — это скромный код. Поэтому используйте библиотеки и включайте в них ссылку на документацию. В C++ легко добавить комментарий к строке, где вы #include (включаете) файл заголовка. В остальных языках вы сможете найти другое место для комментария, чтобы люди, которые будут копипастить позже, вставили ссылку, а также код, использующий библиотеку.

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

Щедрость и трудолюбие

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

Обмен информацией также отличается щедростью; это те, кто думает: "Моя работа в безопасности, если мы все сможем это сделать". Их комментарии поучительны, они выбрали хорошие имена, и расположили код в порядке, который имеет понятный читателю смысл: "Сначала мы готовим заказ, потом отправляем его, далее обновляем инвентаризацию. Я понял". Добиться такой ясности нелегко, и, как правило, это не то, что вы пишете с первого раза. Кто-то приложил усилия, чтобы сделать этот код хорошим.

Иногда код просто поражает вас своим великолепием. Это ясно и очевидно правильно, его очень легко понять. Это совсем не значит, что это умно. Я имею в виду, что это наглядно. Рассмотрим этот C#:

var creditScore = application.CreditScore;
switch (creditScore)
{
case int n when (n <= 50):
return false;
case int n when (n > 50):
return true;
default:
return false;
}

Этот код неплох. Он компилируется без предупреждений, и в нем реализована необходимая логика. Но здесь есть три кейса (два диапазона и значение по умолчанию) и много мест, где можно допустить ошибки. Кто-то может вернуть true с помощью двух операторов возврата вместо одного. Можно изменить значение 50 в первом случае, но забыть изменить его во втором. И так далее. Самое главное, что вам потребуется некоторое время, чтобы разобраться во всем этом и понять какое правило здесь реализовано. Сравните с этой строкой:

return (application.CreditScore > 50);

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

Редко, когда просматривая существующий код команды, можно обнаружить, что он свободно компилируется, компонуется, запускается и проходит тесты. Конечно, компилируется, но есть предупреждения. Может быть, сотни. И все члены команды знают, что их 417, а если будет 418, то кто-то должен разобраться в этом. Или он запускается, но при старте вы получаете исключение, поэтому просто нажимайте "Продолжить" и не беспокойтесь об этом. Либо он оставляет после себя несколько stray файлов, и вам приходится вручную удалять их, прежде чем запустить его снова. Или он прошел тесты, но их было всего семь. Когда я встречаю код, который компилируется без предупреждений, работает нормально без ручного вмешательства, имеет полные и хорошо документированные тесты, то чувствую, что обо мне действительно заботятся. Вот тот, кого не нужно просить сделать все правильно. Они применяют инструменты не ради их существования, не для развлечения, а для того, чтобы все работало как надо.

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

Выбирайте положительные эмоции

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

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


Приглашаем всех желающих на открытый урок «Системы контроля версий, Git». На нем мы поговорим про системы управления версиями (больше, конечно же, про Git), а также продемонстрируем как начать работать с проектом на примере Git + GitHub. Регистрация здесь.

Комментарии (5)


  1. MentalBlood
    06.04.2022 20:17

    "Абстракция? По-моему, это похоже на работу!"

    Это какая-то неправильная, тупая лень )


  1. lolipoka
    07.04.2022 07:48

    А как переводчик смотрел оригинал? Автор - женщина, если что.


  1. lavifae
    07.04.2022 07:51

    Надеюсь, что как можно больше людей поймут и увидят сопоставление лентяев и уставших от кранча программистов)

    Спасибо за статью. Очень заинтересовали исследования April Wensel и Steve Miller, можете поделиться источником? Или как/где искать подобное)


  1. hunnuh
    07.04.2022 13:03
    +1

    Kate Gregory - женщина, по отношению к ней используется местоимение "she" (https://www.codemag.com/People/Bio/Kate.Gregory). По тексту настоящего перевода создается впечатление, что оригинальная статья написана мужчиной

    (используются "мужские" окончания глаголов:

    До недавних пор я не тратил много времени...

    Я приложил много усилий...

    Поскольку я упомянул эмоции в заголовке...).

    Было бы весьма любезно исправить данную оплошность. Читать дальше не смог.


    1. rikki_tikki Автор
      07.04.2022 18:33
      +2

      Спасибо, исправили