Чистота и порядок: 3 правила для идеальной базы кода

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

Наглядная иллюстрация того, что представляет из себя грязный код: 

Кривая Бема

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

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

1. Правило 20% 

Правило 20% решает вопрос с техническим долгом, для устранения которого рекомендуется выделять именно такой объем времени в спринте. 

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

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

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

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

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

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

С одной командой мы условились уделять техническому долгу (т.е. элементам, не связанным с разработкой продукта) 20% временных затрат, оцененных по методу Story Points. После обозначения и оценки тикетов (задач) мы использовали их в спринте для проработки намеченных элементов. Это позволило поддерживать чистоту приложения, инфраструктуру и даже инструменты разработки. 

20% предлагается как вариант. 

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

2. Выявление грязного кода до слияния 

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

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

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

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

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

Еще одной превентивной мерой является линтинг. 

Линтеры  —  самый распространенный способ предотвратить появление кода с запашком в системе. Для JavaScript используется Eslint, для Python  —  autopep8. Почти в каждом языке есть встроенные и сторонние пакеты для линтинга, которые можно адаптировать к командным рекомендациям и правилам оформления кода. Они требуются для предотвращения слияния грязного кода. 

3. Правило бойскаутов 

Как говорил Роберт Сесил Мартин (Дядя Боб): “Взял модуль на доработку, верни его в более чистом виде”.

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

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

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

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

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

Однако здесь есть свои “но”. 

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

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

Вы отвечаете за результат 

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

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Scott Pickthorn: 3 Steps to Take Care of Your Codebase

Предыдущая статьяУменьшаем размер образа Docker для приложения Next.js
Следующая статьяКак использовать инструменты статического анализа в коде Python