Pull to refresh
67.74
Rating
Miro
Online collaborative whiteboard platform

Как не продолбать архитектуру в погоне за фичами

Miro corporate blogWebsite developmentDevelopment Management

Я работаю в Miro со дня основания, вначале как фронтенд инженер, сейчас как менеджер core-команд, которые разрабатывают внутреннее ядро канваса и realtime-коллаборации на нём.

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

  • Перешагнули рубеж в 10 миллионов регистраций;

  • Пиковая онлайн-нагрузка за год выросла в 7 раз;

  • Команда разработки выросла в 2 раза (инженеры, продакты, дизайнеры);

Выглядит круто! Но есть нюансы.

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

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

Так мы сталкиваемся с задачей “Как сохранить скорость разработки фичей и гибкость архитектуры на стадии роста?”. Откатимся назад в прошлое и будем пробовать разные подходы чтобы прийти к тому, что есть сейчас.

Выделим 20% времени на рефакторинг и улучшения

И так, ситуация X времени назад. У нас есть несколько фичевых команд, которые разрабатывают новую функциональность. Команды самостоятельно реализуют фичу от начала до конца и могут менять любой необходимый для этого код. У каждой команды свой продакт-менеджер, он управляет фокусом и бэклогом команды. Цель продакт-менеджера – достигать определённых бизнес-метрик.

Между продакт-менеджером и инженерами часто возникает типичный конфликт “качественно” vs “быстро”.

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

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

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

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

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

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

Закрепим ответственность за кодом за конкретными командами

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

Что значит “владеть кодом”:

  • Ревьюить пул-реквесты на любые изменения;

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

  • Помогать и консультировать другие команды;

  • Приводить код в соответствие критериям качества, принятым в компании, например, иметь тесты и документацию на код;

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

Как это выглядит с технической точки зрения.

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

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

По ходу распределения компонентов у нас “вскрылось” довольно много кода, который в принципе не ложился на фичевые команды в долгосрочной перспективе.

Что делать? Создадим новый тип команд — core-команды, которые будут отвечать за развитие “фундамента”.

Вынесем фокус на архитектуру и системные задачи в отдельные core-команды

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

Цель core-команд — развитие внутренней платформы, на базе которой остальные команды смогут быстрее и качественнее строить новую функциональность и развивать существующую.

Примеры задач core-команды:

  • Упрощение доменной модели данных и предоставление API для неё;

  • Создание внутреннего фреймворка для фичевых команд;

  • Изоляция слоёв приложения;

  • Стабильность и производительность сервиса;

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

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

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

Окей. Создали команды. Будет ли этого достаточно или что-то может пойти не так?

Разумеется может.

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

Есть много способов уйти не туда. Вопрос — как сфокусироваться на важном?

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

Создадим техническую стратегию

Стратегия должна помочь core-командам понять, что на самом деле мы собираемся построить не через месяц, а через несколько лет. Не так важно, как это называть: техническая стратегия, архитектурное видение, Painted Picture, просто план, — важнее это формализовать, чтобы перенести идеи из головы в документ и договориться, что все согласны со стратегией и понимают её одинаково.

Техническая стратегия включает три источника требований:

  • Бизнес: видение развития компании, продуктовая стратегия, крупные фичи, которые мы планируем реализовать в будущем, но не можем из-за блокеров в архитектуре;

  • Надёжность и производительность: какой ожидается рост нагрузки, под что стоит оптимизировать производительность, какие метрики для нас приоритетные;

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

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

  • Целевое разбитие на компоненты и слои из которых должно состоять приложение;

  • Зоны ответственности команд: явно договорились, какие команды за какие слои и компоненты отвечают;

  • Целевая модель данных: объекты в системе и взаимосвязи между ними;

  • Перечень крупных изменений в core-компонентах, которые ускорят или упростят разработку, а также разлочат продуктовые фичи.

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

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

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

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

Итого

Шаги, которые могут помочь сохранить нужный уровень гибкости и скорости разработки новой функциональности, при условии быстрого роста продукта и размеров команды:

  • Дать фичевым командам выделенное время на работу с техническим долгом;

  • Договориться о политиках владения кодом и превратить это в процесс;

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

  • Целевую архитектуру вырабатываем вместе с бизнесом, фиксируем описание, планируем реализацию;

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

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

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

Tags:архитектурастратегиятехдолгуправлениевладение кодом
Hubs: Miro corporate blog Website development Development Management
Total votes 29: ↑28 and ↓1 +27
Views9K

Comments 16

Only those users with full accounts are able to leave comments. Log in, please.

Top of the last 24 hours

Information

Founded
Location
Россия
Website
miro.com
Employees
201–500 employees
Registered
Representative
Сергей Шабалин

Habr blog