Как создать архитектуру фронтенд-приложения, если ее нет от слова «совсем»

062649b17157767b2bb03d5a13c66520.png

Всем привет! На связи Вадим Королев, архитектор на Web HiFi-стриминга Звук. Сегодня я хочу поделиться своим опытом и рассказать, как создать архитектуру фронтенд-приложения, если ее еще нет в вашей компании.

Как понять, что пора взяться за архитектуру

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

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

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

Работа на этапе R&D: с чего начать?  

Для начала нужно определить, какого масштаба ваш проект: маленький, средний или большой. Для маленьких проектов, если у вас до этого не было никакого архитектурного опыта, скорее всего, подойдет какая-нибудь базовая методология по типу Feature-Sliced Design. Этого обычно достаточно, чтобы закрыть большую часть проблем, а для того, чтобы успешно использовать методологию, подойдут просто внутренние договоренности (вы должны говорить на одном языке, когда начинаете использовать методологию, поэтому синхронизируйтесь по терминологии и смыслам, которые каждый участник команды вкладывает в то или иное определение). 

Если проект среднего масштаба, стоит проконсультироваться с коллегами, которые занимаются Backend (если такие есть на проекте), потому что обычно у них эта тема более прокачана. На этом этапе вы можете коллективно спроектировать слой BFF, который может значительно облегчить вам масштабирование в лигу больших проектов. Другими словами, вы сможете адаптировать архитектуру фронта под вашу архитектуру бэкенда. Тогда случится win-win для всех отделов, а вам в итоге будет проще все это «склеивать».

Если же ваш проект большой, скорее всего, над ним одновременно работает много команд. В этом случае стоит задуматься о создании Core-команды фронтенда, если у вас её до сих пор нет (у нас в Звуке она есть). Эти люди должны обладать большой насмотренностью в проекте, понимать всю внутреннюю магию и отталкиваться от попсовых решений к более частным. Архитектура больших проектов более комплексная и имеет кучу нюансов, потому что есть специфические вещи, ориентированные непосредственно на вашу компанию и бизнес.

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

af32271609c7629a2b4878887c68ad34.jpg

Ошибки, которых невозможно избежать

Выстроить архитектуру, не совершив совсем никаких ошибок, не получится. Приготовьтесь к тому, что вам придется потратить некоторое время на бесполезный поиск готовых решений в интернете. Конечно, можно пойти очень простым путем, взяв готовую архитектуру. Вроде той, что описана в «Чистой архитектуре» Роберта Мартина. Написать поверх нее свой код и получить кучу проблем в виде полнейшего непонимания, а зачем вообще умные дядьки так сделали и нужно ли это всё именно вам (и это первая ошибка). Но есть и плюс — так вы сможете создать для себя какой-то базис, от которого дальше можно будет отталкиваться. А еще адаптация готового решения поможет на старте прокачать архитекторское мышление и понять, как действовали другие люди при проектировании архитектур, куда двигались и какие решения принимали.

Вторая ошибка — затягивать тестирование и не давать «пощупать» ваши наработки разработчикам, для которых вы и делаете архитектуру. Можно до победного сидеть на синках, докручивать что-то на теоретических примерах, думать, что вы не покрыли все кейсы практического применения с помощью утилит, прежде чем дать их в эксплуатацию разработчикам. Но намного быстрее будет сразу отдать инструменты в альфа-версии команде разработки и попросить попользоваться ими. Все возникающие вопросы в ходе работы можно обсуждать на консультациях. Разрабы будут добавлять что-то в готовый проект, и, возможно, в будущем это повторно придется рефакторить (спойлер: мы так делали, было неприятно, но благодаря этому мы набили руку в создании мягких планов миграции. В будущем, возможно, дорастем до codemod«ов). С помощью обратной связи вы соберете много инсайтов, которые помогут вам при проектировании последующих версий.

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

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

Итог: Меньше говори — больше делай!

Инструменты и методологии в помощь архитектору

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

Следующий инструмент — диаграммы в коде. Если команда уже набросала какие-то концептуальные вещи, их нужно финализировать в документации. Для эффективной фиксации принятых решений в виде диаграмм можно использовать нотацию plantUML. Это стандартизированный язык разметки, позволяющий строить диаграммы разного уровня сложности и разных типов, которые покроют абсолютно любые ваши кейсы. Для неё есть обширная документация на русском языке, а рутинный процесс преобразования можно легко упростить с помощью любой доступной нейросети (например, Gigachat).

Чем это полезно? Вы можете вести фиксацию всех изменений в ваших диаграммах, и с помощью инструментов git наглядно посмотреть по истории коммитов, почему и когда что-то поменялось. Также для plantUML есть куча интеграций с IDE и средами, где есть встраиваемые плагины. Например, у нас в конфлюенсе, даже в очень старой версии, есть плагин, позволяющий публиковать схемы, отрендеренные в SVG. 

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

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

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

Опыт команды Звука: процесс внедрения в старый проект

В этой части я хотел бы поделиться реальным кейсом из жизни нашей команды. 

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

Мы взяли готовую фичу из проекта Звук-Web. Ей стало FM-радио — не самая популярная фича со старым кодом, который был не очень хорошо написан. Команда перенесла ее на новые рельсы с помощью тулинга, который мы разработали.

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

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

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

Документация для разработчиков

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

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

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

Измеряем эффективность решений

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

Второй показатель — это метрики производительности вашего приложения. С этим запросом можно сходить в отдел мониторинга. У лида команды веба тоже должны быть доступы к интересующим метрикам. И, в первую очередь, здесь не должна протекать память в приложении. У нашей команды был инцидент, который выявил определенный баг, приводивший к утечкам памяти. Это привело к лагам и лишним перезагрузкам приложения в кластере. Некоторое время мы не могли понять, почему так происходит. Оказалось, что разработчик просто некорректно воспользовался инструментарием, не до конца разобравшись в том, как пользоваться сущностями архитектуры. Это привело к появлению циклических зависимостей и, следовательно, утечке памяти. Разобравшись в причине проблемы, мы зафиксировали в документации, что так делать нельзя. Производительность всегда должна сохраняться на прежнем уровне (и даже становиться лучше со временем, если у вас стоит такая задача при разработке архитектуры).

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

Спасибо, что прочитали материал! Буду рад ответить на вопросы в комментариях и обсудить ваш опыт создания архитектуры для фронтенда.

© Habrahabr.ru