«Недостаточно, чтобы код работал».
Роберт С. Мартин

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

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

Что такое чистый код?

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

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

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

Именование вещей

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

Фил Карлтон
https://www.karlton.org/2017/12/naming-things-hard/

Итак, можем ли мы упростить задачу? Соблюдение определенных правил — хорошее начало. У каждого языка программирования есть свои соглашения, что нужно писать с большой буквы, а что нет. Использовать ли camelCase, змеиный_кейс, кебаб-кейс или что-то другое.
Далее идут правила объектно-ориентированного программирования. Классы — это существительные, потому что они представляют объекты, а методы — это глаголы, поскольку они что-то делают. А вот с интерфейсами дело обстоит сложнее. Существуют различные соглашения для интерфейсов. Некоторые добавляют к ним префикс IIList, другие предлагают добавлять к ним префикс -able или -ing — Equatable, ProgresReporting. Мое первое предложение по этому поводу — следовать соглашениям в кодовой базе, над которой вы работаете. Если у вас есть возможность выбора, я предлагаю отбросить любые префиксы «I» или любые суффиксы «Протокол» или «Интерфейс» и назвать их так, как вы бы назвали любой тип. Идея интерфейсов состоит в том, чтобы скрыть реализацию, поэтому тип реализации должен иметь хорошее имя.
Помимо соглашений, очень поможет использование имен на английском языке с правильным написанием. Большинство языков программирования поддерживают символы Unicode, а некоторые даже позволяют использовать эмодзи для переменных и функций. Поэтому может выглядеть круто и заманчиво определить функцию журнала следующим образом:

Log.⚠️("Warning")
// instead of
Log.warning("Warning")

Но в конечном итоге вы увидите, что это не очень практично. Автоматическое завершение IDE будет сложнее использовать. Поиск по вашему коду также станет сложнее. В современных IDE есть проверка орфографии, так что просто включите ее, все будут благодарны в следующий раз, когда попытаетесь найти что-нибудь про учетные записи (а не учетные записи 😁)

Совет 1. Ознакомьтесь с соглашениями об именах и следуйте им

В дополнение к соглашениям я могу дать еще несколько советов.
Не кодируйте информацию о типе в имени. Были времена, когда имена были ограничены по длине, а IDE не предоставляли столько контекста, а такие вещи, как венгерская нотация, были хорошей практикой. Но сейчас они не нужны. Имя типа accountList не дает никакой дополнительной информации, которую вы не видите на первый взгляд. Просто accounts короче и дает достаточно контекста — набор Account. Когда вам нужно будет его использовать, IDE покажет, каков его фактический тип, и предложит соответствующие методы.
Не полагайтесь на комментарии, чтобы объяснить имя. Вместо этого попробуйте придумать имя получше. Мы рассмотрим эту тему в следующем разделе.
Учитывайте контекст. «Штат» может означать одно в контексте адреса, штата в такой стране, как США или Индия, или совершенно другое — в контексте состояния объекта.

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

Совет 2: Имена должны раскрывать намерения

Комментарии

Мы все видели такие комментарии:

// Get primary accounts with non zero balance
accounts.stream()
    .filter(account -> account.isPrimary() && !BigDecimal.ZERO.equals(account.getBalance()))
    .collect(Collectors.toList());

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

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

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

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

Совет 3. Комментарии должны объяснять не то, что делает код, а то, почему он это делает

Функции

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

Один из самых важных советов, которым вы можете следовать в отношении функций, — делать их небольшими. Если вы посмотрите в Интернете, большинство людей остановятся на том, что вам не потребуется больше минуты или двух, чтобы понять, что делает функция. Разделение длинных функций на более короткие очень помогает улучшить читабельность и понятность вашего кода. И если вы слышали о глубоких стеках вызовов и беспокоитесь о снижении производительности, вам не следует этого делать. Если у вас есть такие ограничения, вы это знаете :) Для остальных просто старайтесь, чтобы функции были короткими и в лучшем случае выполняли одно действие. Или, говоря словами SOLID, нести единственную ответственность. Следование этому совету также облегчит присвоение имен. Потому что, если ваша функция делает что-то одно, придумать хорошее имя будет не так уж и сложно.

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

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

Совет 4: Делайте функции короткими и без побочных эффектов

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

Совет 5: Будьте хорошим гражданином или бойскаутом ;)

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

Ссылки:
Роберт К. Мартин — Чистый код: руководство по гибкому программному мастерству
Руководство по проектированию Swift API — https://www.swift.org/documentation/api-design-guidelines/< br /> Цитата: https://www.goodreads.com/work/quotes/3779106-clean-code-a-handbook-of-agile-software-craftsmanship-robert-c-martin
Избранное изображение Учетные данные: https://www.pexels.com/@kevin-ku-92347