Екатерина Сазонова, переводчик-фрилансер и студентка «Нетологии», специально для блога перевела статью Carl Tashian о том, как продакт- и проджект-менеджерам справляться с техническим долгом.
О проблемах разработки программного обеспечения, его оценке, контроле стоимости, тестировании написано огромное количество книг.
Технический долг (также известный как долг кодинга) — это метафора-неологизм, обозначающий проблему, возникающую при наличии в настоящем факта незавершенной работы в прошлом или откладывание на будущее выполнение той работы, которая должна быть выполнена в настоящем. Также технический долг является неизбежным следствием плохой продуманности структуры системы, непродуманности архитектуры программного обеспечения или некачественную разработку ПО, вследствие которой выполненная работа сразу же требует переделки. Долг может рассматриваться в виде работы, которую необходимо проделать, пока задача не сможет считаться выполненной. Если долг не погашается, то он будет продолжать увеличиваться, что усложнит дальнейшую разработку, — Википедия.
Хочу поделиться с вами проверенными практиками, которые помогли мне как техническому менеджеру держать под контролем технический долг в растущем проекте.
Поддерживайте гибкость в нужных местах
Проектируйте программное обеспечение так же, как вы проектировали бы здание. Что-то в строительстве продвигается медленно, что-то — быстро. Некоторые компоненты, например, мебель или покраска стен, не имеют прямого отношения к самому зданию. При этом очень трудно поменять угол, под которым стены расположены друг к другу. Нужно расставлять приоритеты.
Программа обучения: «Руководитель digital-продукта»
Понимание того, что может быть гибким в программе, а что — нет, относится не только к текущим требованиям, но и к будущим. Вот почему так сложно создавать софт. Вы не просто поставляете свой технологический продукт, вы пытаетесь предсказать будущее. А будущее покрыто мраком, всегда есть риск преждевременной оптимизации. Придется сделать выбор: какой компонент фундаментален, а какой можно легко изменить.
Слово software (дословно «мягкое изделие», появилось в противовес «твердому изделию» — hardware) искажает суть понятия, потому что подразумевает гибкость во всем. Гибкость во всем — это идеал, к которому нужно стремиться. Однако, правда такова, что более строгую систему с очень тесно связанными компонентами построить намного проще. К примеру, можно утверждать, что в монолитном приложении элементы связаны между собой сильнее, чем в наборе микросервисов. Очевидное преимущество монолитного приложения — в его простоте. Хотите написать хоть строчку кода для приложения, основанного на микросервисах? Изучите сначала гигантский список требований к обмену данными, координации и доступности элементов системы.
Это не значит, что микросервисы решают проблему связи между модулями. Они связывают модули с сетью, которая позволяет выстроить четкие, очерченные границы доменов, но само соединение неизбежно.
Гибкость стоит дорого. Не могу даже сосчитать, сколько раз я создавал что-то с представлением о том, как изменятся в будущем требования, а потом обнаруживал, что менять нужно именно «неподвижные» части, а гибкие не обязательно должны быть гибкими.
Сначала я думал, что мне просто не везет, но теперь я понимаю, что ошибался при планировании.
Софт, в отличие от здания, устаревает по-другому. Если требования не меняются, фундамент не сдвинется и не начнет разрушаться, как это происходит со зданием. Программное обеспечение не изнашивается. Однако на его фундамент влияют новые требования. Стартапам очень сложно сделать правильный выбор. Эту проблему пытаются решить с помощью облачных сервисов, закладывая с самого начала возможность масштабирования. Оптимизация управления расходами и скоростью по мере того как вы будете расти потребует много фундаментальной работы. Даже с современными облачными решениями, механизмами управления микросервисами и так далее.
Рефакторинг для скорости
Рефакторинг — один из лучших способов увеличить общую скорость работы. Об этом уже было много сказано. В любой достаточно большой кодовой базе есть что порефакторить. Главное — рефакторить в нужном месте, там, где понадобится упрощение и гибкость в будущем. Чтобы это не напоминало игру в угадайку, будет правильным рефакторить до внедрения новых функций.
Прежде чем написать код, смиритесь с тем, что его придется выбросить
Простой способ уменьшить технический долг — понять, что любой код является лишь временным экспериментом. Например, вы решили создать отдельную ветку кода и быстро набросать прототип, который получится внедрить. Даже если с этой фичей все будет хорошо, вам придется написать код заново как следует, а старый выкинуть. Такое прототипирование специфично и несет много рисков: некоторым людям в вашей команде придется снизить свои стандарты. Однако этот метод сбережет ваше время.
Работайте с тестами и анализируйте код
Тестирование — это образ жизни, священная практика. Даже в маленьких проектах тестирование экономит больше времени, чем занимает сам процесс. Иногда это видно сразу, иногда — позже.
В компании должно быть принято проводить code review. Неважно, сколько тестов вы пишете, хорошо ли вы умеете рефакторить. Другие люди заметят моменты, которые вы пропустили. Ошибки. Баги. Опечатки. Да всё что угодно.
Во многих компаниях по три пары глаз проверяют каждую строчку кода — считаю, это могло бы стать общим правилом.
Частота тестирования и проведения code review должна быть соизмерима с вредом, нанесенным проекту в случае провала. Исходный код требует более тщательной проверки, чем код интерфейса. Любое программное обеспечение, связанное с работой инсулиновой помпы, должно быть протестировано серьезнее, чем любое мобильное приложение. Можете себе представить команду, работающую над инсулиновой помпой, с лозунгом «Делай быстро и круши»? (мантра разработки Фейсбука и девиз Марка Цукерберга «Make fast and break things»).
Убейте плохо работающие фичи
Один мой знакомый инженер Ноа Торп как-то сказал мне: «Мы платим за каждую строчку кода каждый день». Чем меньше кода, тем меньше вы платите. Когда я работаю над проектом, мне важно, как работает каждая фича. Я регулярно собираю команду, чтобы решить, какие функции улучшить, а что убрать. Это значит временами признаваться себе в том, что фича, которая вам нравится, просто не работает.
Идеальная ситуация такова: вы понимаете, что фича неправильно будет работать еще до того, как пишете код. На первой линии защиты бумажные прототипы и тестирования на пользователях. Тем не менее, на вас всегда давят. Всегда слышен галдеж людей, использующих продукт и просящих добавить такие жуткие возможности, которые никогда не надо реализовывать. Или такие фичи, которые можно бы добавить, но позже. Вот где встречаются управление продуктом и техническое проектирование: даже если создать новую фичу — обычное дело, за это все равно придется платить.
Сведите зависимости к минимуму
Приходится платить и за зависимости тоже. Зависимости бывают внутренние и внешние. Внутренние — это библиотеки и фреймворки, от которых зависит ваше программное обеспечение. Внешние — это сервисы, с которыми связан ваш софт. От сервисов вы зависите вдвойне, потому что обычно с ними связаны и библиотеки.
Добавляя библиотеку к вашему проекту, вы платите за всю библиотеку и ваше пользование ей. Итак, вам нужно обосновать необходимость каждой библиотеки, каждого плагина. Даже самых маленьких. Они добавляются быстро. Если у вас взвешенный подход, вы удивитесь, насколько быстро вы продвинетесь.
Применять все эти методы проще, если они становятся общими принципами работы в вашей компании и для их использования создается благоприятная среда. Поддерживайте высокий уровень code review с запросами на включение кода (pull request). Продолжайте постоянно тестировать, поддерживая систему непрерывной интеграции (Continuous Integration). Ежемесячно обсуждайте основные фичи. Держите под рукой бумажные книги, которые рассказывают о правильных подходах, например, «Рефакторинг: улучшение структуры существующего кода» (“Refactoring: improving the design of the existing code”). И не забывайте их читать!
Читать ещё: «Лучший софт для управления проектами и командой: от планирования до отчетности»
Важно четко понимать, что вы строите. Это будет тайное убежище на берегу моря, типовое жилье или стеклянный музей искусств? Ответ на этот вопрос должен совпадать у всей команды. Вот почему управление техническим долгом — это не только работа технического менеджера или разработчика. Это общая работа. Ведь она влияет на каждый шаг процесса разработки продукта, начиная с планирования.
Мнение автора и редакции может не совпадать. Хотите написать колонку для «Нетологии»? Читайте наши условия публикации.