«Любой дурак может написать код, понятный компьютеру. Хорошие программисты пишут код, понятный людям», — сказал культовый британский разработчик программного обеспечения Мартин Фаулер и в этом утверждении присутствует доля правды. То есть, когда разработчик пишет код, он должен фокусироваться не только на том, чтобы тот был рабочим, но и понятным будущим «читателям».

Кстати, сейчас у нас проходит «Конкурс красоты кода». Регистрируйтесь и покажите, как должен выглядеть по‑настоящему чистый код — лаконичный, эффективный и понятный. 

Как можно управлять страной, в которой производится двести сорок шесть сортов сыра?

Шарль де Голль

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

Это термин, используемый для обозначения кода, который легко читать, понимать и поддерживать. Популяризирован силами Роберта Сесила Мартина (Дядя Боб), который написал «Чистый код: Справочник по гибкому программному мастерству» в 2008 году. В этой книге автор представил набор принципов и практик по написанию чистого кода, таких как: использование осмысленных имен, коротких функций, понятных комментариев и единообразного форматирования.

Чистый код — это код, который легко понять и легко изменить.

Самое популярное определение

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

Кого волнует чистый код?

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

Основная причина в том, что код часто является наименее заметным аспектом разработки ПО. Конечно, сами программисты заботятся об этом. Скорее всего вы часто слышите, как они говорят о «красивом» или даже «элегантном коде». Но кто хоть когда‑то слышал замечания конечного пользователя об эстетике кода? По правде говоря, им все равно. Единственное, что волнует пользователей, это то, что программа решает проблему.

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

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

Управление сложностью

Многие думают, что основная задача разработчика ПО — писать код, что не совсем верно. Поскольку основная задача — управлять сложностью, то есть они должны использовать код, чтобы скрыть или устранить сложность при разработке приложений.

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

  1. Больше усилий при внесении изменений. Порой даже простейшая модификация требует изменение кода в разных местах.

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

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

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

Пойди туда — не знаю куда!

И по всей вероятности, он не узнает об этом, пока не появится ошибка после внесения изменений.

Причины сложности

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

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

В информатике есть только два сложных вопроса: инвалидация кэша и присвоение имен.

Фил Картон

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

Управление зависимостью

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

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

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

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

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

Итеративная инкрементальная сложность

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

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

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

Роберт С. Мартин

Важные мысли

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

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

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

Почему важен чистый код?

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

Ценность для программистов:

  • помогает обнаруживать, понимать и решать проблемы в процессе написания кода;

  • сокращает «переделку» и цикл обратной связи, что прямо влияет на производительность;

  • на исправление чужого кода уходит меньше времени.

Ценность для бизнеса:

  • значительно сокращает количество непредвиденных простоев и затраты на решение проблем;

  • увеличивает скорость разработки программного обеспечения.

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

Принципы чистого кода

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

  1. Значимые имена переменных и функций. Правильно выбранное имя может передать цель, делая код более понятным.

  2. Краткость функции и методов. Более короткие функции легче понимать, тестировать и поддерживать.

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

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

  5. Дублирование кода. Снижает риск ошибок.

  6. Осмысленные пробелы. Повышает читабельность и логику, снижает когнитивную нагрузку.

  7. Обработка ошибок. Данный блок предотвращает неожиданные сбои и предоставляет ценную информацию для отладки.

  8. Тестирование. Заставляет заранее учитывать пограничные случаи и ожидаемое поведение.

  9. Рефакторинг. Помогает поддерживать чистоту кода по мере развития проекта.

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

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

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

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


  1. saipr
    24.10.2024 06:16

    «Любой дурак может написать код, понятный компьютеру. Хорошие программисты пишут код, понятный людям»

    Для меня таким кодом понятным для людей и даже откровением в 1987 году стал код операционной системы Minix. Этот код открыл мне глаза на многое в искусстве написания программ.


  1. vvbob
    24.10.2024 06:16

    Все это прекрасно, но все эти призывы писать чистый код мне напоминают советы в духе - "не болей", "будь богатым, не будь бедным" и все прочее в таком духе.

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

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


  1. AdrianoVisoccini
    24.10.2024 06:16

    Самая большая проблема с КлинКодом в том, что некоторые отдельные люди не способны осознать разницу между рекомендациями и незыблемыми и нерушимыми истинами бытия.
    Есть занятное видео https://youtu.be/tD5NrevFtbU?si=FBK2mnyYX3VZvcuv где автор показывает на практике, прямо на примере из книги про КлинКод как игнорирование этих принципов помогает улучшить производительность в 10,20,40(!) раз. В дальнейшем на почве этого ролика у автора были дебаты с самим Дядюшкой Бобом, в которых последний дико демеджконтролил, попытался свести все к ложному консенсусу, а потом совершил RageQuit и больше не обсуждает эту тему. Короткий разбор ситуации есть вот тут: https://youtu.be/oFiY7EEtAW4?si=3_IzWIihFqSlWpij

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


    1. Artyomcool
      24.10.2024 06:16

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

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


  1. orefkov
    24.10.2024 06:16

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


  1. EgorovDenis
    24.10.2024 06:16

    В информатике есть только два сложных вопроса: инвалидация кэша и присвоение имен.

    Добавлю третью проблему, которую практически никогда не решают правильно: удаление старых (неактивных) данных.

    Чаще всего обходятся механизмом "soft delete", которая ведет к куче проблем с перепроверкой флагов и рекурсивной зависимостью других компонентов. Другой способ ("hard delete") тоже непростой, так как ты либо не можешь удалить элемент из-за FK, либо удаляешь элемент и все зависимые от него элементы с помощью каскадного удаления, которые не хотел бы удалять.