Что менеджеру проектов нужно знать про технический долг

by Владимир Бычко

Изображение с unsplash.com, автор Tommaso Curre

Вводная

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

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

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

Костыли

В целом, можно сделать либо быстро, либо правильно. Быстро и правильно, как правило, не получается. Выходит либо медленно и правильно, либо медленно и неправильно. И чаще всего, бизнес требует быстро. Сделать «на тройку», чтобы опередить конкурентов, выпустить фичу побыстрее, захватить кусок рынка. В целом, подход работает, но он порождает этот самый технический долг, который потом придётся возвращать.

Разработчики говорят «закостылить». Определение костыля такое:

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

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

Так не делайте костылей, делайте всё правильно сразу, скажете вы. Но этот путь — верный способ навсегда испортить отношения с бизнес-подразделением. Почему, например, любой пользователь знает об Excel, а о Lotus 123 не знает почти никто? Потому что когда-то давно, после выхода процессора с новой архитектурой, разработчики Экселя закостылили решение, вышли на рынок раньше Лотуса, старая версия которого не работала на новом проце и захватили рынок.

Велосипеды

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

Под велосипедом («созданием велосипеда») в программировании подразумевают разработку того, что уже давно изобретено, причем часто в более продуманном и совершенном виде. 

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

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

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

Ричард Бакминстер Фуллер.

Ричард Бакминстер Фуллер

американский архитектор, дизайнер, инженер.

Архитектура

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

В семидесятые годы двадцатого века один строительный архитектор (Кристофер Александр) придумал и скомпоновал набор паттернов проектирования для строительной отрасли.

Язык шаблонов, Кристофер Александер.
Книжка Кристофера Александера «Язык шаблонов», настольная книга любого строительного архитектора.

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

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

Рефакторинг

Одним из способов борьбы с техническим долгом и легаси является рефáкторинг. Библией рефакторинга для разработчиков является книжка Мартина Фаулера «Рефакторинг: улучшение существующего кода».

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

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

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

Выводы

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

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

Услышь меня и вытащи из омута. Технический долг.