Чистая архитектура фронтенда



Книга Чистая архитектура фронтенда

В этой статье речь пойдет об архитектуре фронтенда, проектирование которой подчиняется множеству принципов, в том числе 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 на несколько поддоменов. Каждый поддомен имеет собственный ограниченный контекст и единый язык. Это может выглядеть так, как показано на рисунке ниже.


Применение концепций DDD

Каждый поддомен использует уровневую архитектуру, взаимодействуя с другими поддоменами через 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, предметно-ориентированного проектирования) к архитектуре фронтенда. И, наконец, ознакомились с правилами создания компонентов с учетом развития бизнес-логики, которые позволяют коду оставаться ожидаемо поддерживаемым.


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



271   0  

Comments

    Ничего не найдено.