Модульная архитектура очень важна для любого крупномасштабного приложения. Она помогает разделить домены приложения, позволяет разработчикам сосредоточиться только на своих конкретных областях и значительно упрощает процесс внедрения. Кроме того, если вы решите разделить монолит на микросервисы, это будет менее болезненно.
Основная идея модульного проектирования заключается в том, чтобы организовать файлы проекта на основе их назначения, а не типа.
Одна из самых распространенных проблем, с которой вы столкнетесь в процессе модульного проектирования, — это ловушка круговой зависимости между модулями. Циркулярные зависимости часто являются индикатором необходимости извлечения третьего модуля или слияния двух.
Но как их организовать?
Многослойные модули
Я лично сталкивался с проблемой круговых зависимостей в КАЖДОМ проекте, над которым я работал.
Однажды, когда я диагностировал структуру одного из своих приложений, чтобы найти источник круговых зависимостей между его модулями, я понял, что модули могут функционировать независимо только до определенного уровня.
В данном конкретном примере проблема заключалась в уровне API (приложение было внутренним сервисом). Мне нужно было агрегировать информацию из нескольких модулей, чтобы в итоге выполнить задачу и выдать результаты разработчикам внешнего интерфейса.
Поэтому я решил изменить структуру проекта с такой:
на эту:
И после завершения процесса рефакторинга между моими модулями больше не было круговых зависимостей. Кроме того, иерархия модулей стала намного проще для понимания.
Как вы можете видеть, эта структура представляет собой комбинацию многоуровневой архитектуры и модульного дизайна. Вы можете персонализировать ее в соответствии со своими потребностями.
Как я теперь организую свои модули?
В настоящее время я разделяю свои модули на 3 основные категории:
/src
/db-modules
/feature-modules
/api-modules
Модули БД
- Они могут самостоятельно управлять и проверять модели баз данных, относящиеся к их доменам
функциональные модули
- Они могут самостоятельно управлять и проверять модели баз данных, относящиеся к их доменам
- Они реализуют логику и выполняют бизнес-задачи самостоятельно
- Они могут импортировать данные из модулей БД
Модули API
- Они могут самостоятельно управлять и проверять модели баз данных, относящиеся к их доменам
- Они реализуют логику и выполняют бизнес-задачи самостоятельно
- Они реализуют интерфейс API и обрабатывают запросы API самостоятельно (не полагаясь на другие модули API)
- Они могут импортировать из модулей БД
- Они могут импортировать из Feature Modules
В принципе, степень, в которой модуль может решать свои собственные задачи, определяет тип модуля. Также вы можете вводить дополнительные группы по мере роста сложности (например: вы можете добавить группу модулей-агрегаторов для интеграции нескольких модулей API, что полезно при работе с микросервисами и внешними API).
Что вы думаете об этой архитектуре? Оставьте комментарий ниже