В этой статье речь пойдет об архитектуре фронтенда, проектирование которой подчиняется множеству принципов, в том числе SOLID, KISS, DRY и DDD.
Почему эта тема меня волнует? Потому что ежедневно мне приходится убеждать не только руководство, но и команды разработчиков в том, что архитектура фронтенда не менее важна, чем архитектура бэкенда.
В чем важность архитектуры фронтенда?
Функциональные и нефункциональные требования должны применяться не только к бэкенду, но и к фронтенду. Именно архитектура фронтенда позволяет полностью реализовать потребности бизнеса. Кроме того, она дает более четкое представление о сложности проектов, тем самым сокращая время их создания, риски и стоимость. Однако, на мой взгляд, наибольшая ценность фронтенд-архитектуры заключается в том, что она обеспечивает поддерживаемость и масштабируемость любого проекта.
Что представляет собой архитектура фронтенда?
Насколько мне известно, чаще всего используется уровневая архитектура. Однако должен признать, что встречал и проекты, в которых применялась гексагональная архитектура.
Ниже представлен простой проект TripAgency.
Какие уровни используются?
- API: DTO (data transfer objects, объекты переноса данных) и сервисы, генерируемые Open-API Generator.
- Service: включает в себя мапперы (DTO во фронтенд-модель и наоборот) и сервисы, которые взаимодействуют с API через конечные точки REST.
- Store: глобальное хранилище, содержащее все данные, получаемые из уровня Service.
- Booking: домен, включающий модели и компоненты. Smart-компоненты (интеллектуальные) взаимодействуют непосредственно с хранилищем, а dumb-компоненты (неинтеллектуальные) могут применяться более чем в одном контексте, поскольку они гораздо примитивнее.
Что может пойти не так при такой архитектуре?
Если правила не определены, то разработчики могут напрямую использовать DTO в своих компонентах или контактировать с уровнем Service, минуя уровень Store. Или, что еще хуже, dumb-компоненты могут контактировать с уровнем Service.
Что нужно сделать для предотвращения этих ошибок?
Просто определить правила, которые не допустят подобного. Одним из наиболее распространенных подходов является введение в проект Bit или Nx.
Bit и Nx — это мощные системы сборки с открытым исходным кодом, предоставляющие инструменты и методики для повышения производительности разработчиков, оптимизации работы CI и поддержания качества кода.
Как в Bit, так и в Nx можно применять правила зависимостей. Поэтому разработчик получит ошибку, если будет использован не тот уровень.
Это правильный подход, но как убедиться в том, что сам домен (в приведенном примере домен Booking) остается поддерживаемым?
Применим некоторые концепции DDD (Domain Driven Design) к домену Booking. Для этого разобьем домен Booking на несколько поддоменов. Каждый поддомен имеет собственный ограниченный контекст и единый язык. Это может выглядеть так, как показано на рисунке ниже.
Каждый поддомен использует уровневую архитектуру, взаимодействуя с другими поддоменами через API. Feature (уровень функций) включает в себя smart-компоненты и сервисы, UI (уровень пользовательского интерфейса) — dumb-компоненты, Domain (уровень домена) — модели, а Util (уровень служебных функций) — все функции, используемые в данном ограниченном контексте.
Теперь у нас более-менее чистая архитектура. Мы близки к цели, но еще не дошли до конца. Одной архитектуры недостаточно, необходимо также, чтобы компоненты, лежащие в основе архитектуры, и бизнес-логика использовали принципы чистого кода. Итак, рассмотрим уровни Feature и UI.
Какие принципы следует применять к компонентам?
Во-первых, следуйте принципам SOLID. Для каждого компонента определите единственное назначение (Single Responsibility Principle, принцип единой ответственности). Используйте композицию, а не наследование (Open-Closed Principle, принцип открытости/закрытости). Не заставляйте компоненты реализовывать неподходящие интерфейсы, поскольку не все методы имеют смысл (Interface Segregation Principle, принцип разделения интерфейсов). И помните, что компоненты не должны напрямую зависеть от низкоуровневых сервисов (Dependency Inversion Principle, принцип инверсии зависимостей).
Во-вторых, при применении бизнес-логики к компоненту, сервису или служебной функции нельзя забывать о принципе KISS (Keep it short and simple — делайте код как можно короче и проще). Почему это важно? Потому что более простой код легче поддерживать.
В-третьих, старайтесь придерживаться принципа DRY (Don’t repeat yourself — не повторяйся). Переносите общую логику в служебные функции или сервисы.
Как понять, чего следует избегать? Иными словами, что такое антишаблоны?
Антишаблоны
Со временем я столкнулся с некоторыми ошибками. Вот самые распространенные из них.
- Импорт ненужных библиотек, которые увеличивают размер пакета.
- Использование вложенных подписок.
- Добавление бизнес-логики в шаблоны.
- Непроверенная бизнес-логика.
Это и есть антишаблоны. Как же быть уверенным в том, что код останется сопровождаемым? Как известно, бизнес-логика со временем развивается. Довольно часто приходится слышать следующее утверждение:
Код увеличился с момента создания. Сначала это был чистый код, а теперь мы имеем нечто, что не может поддерживаться так же легко, как раньше.
Да, это очень распространенная проблема. Справиться с ней помогут простые рекомендации.
- Определите ESLint-правила.
- Используйте stylelint.
- Тестируйте бизнес-логику.
- Создавайте небольшие многократно используемые компоненты.
- Применяйте ES6— и Typescript-функции.
Подведем итоги
Мы рассмотрели пример чистой архитектуры и принципы, которым она подчиняется. Более того, мы убедились в применяемости DDD (Domain-Driven-Design, предметно-ориентированного проектирования) к архитектуре фронтенда. И, наконец, ознакомились с правилами создания компонентов с учетом развития бизнес-логики, которые позволяют коду оставаться ожидаемо поддерживаемым.
Однако команды разработчиков должны придерживаться высоких стандартов, когда речь идет о проверке кода и добавлении новых функций. Иначе чистой архитектуры может оказаться недостаточно для сохранения поддерживаемости кода.
Читайте также:
- Как разделить монолитное приложение на микрофронтенды
- Как построить надежную фронтенд-архитектуру
- Масштабирование фронтенд-приложений в 2023 году
Читайте нас в Telegram, VK и Дзен
Перевод статьи Robert Maier-Silldorff: What is a Clean Frontend Architecture?