Разработка эффективной архитектуры для вашего Android-проекта имеет решающее значение, особенно если вы намерены поддерживать его в долгосрочной перспективе. Выбор стратегии зависит от различных факторов, включая масштаб проекта, ресурсы, цели и технологический стек.
При использовании многомодульной функциональной архитектуры вы можете выиграть от улучшения повторного использования, параллельной разработки и децентрализованного фокуса. Однако необходимо тщательно продумать, как разделить модули — по функциям, доменам или другим критериям, соответствующим конкретным потребностям вашего проекта.
Эта статья посвящена интригующей дискуссии о структурировании многомодульной архитектуры — теме, недавно поднятой в Dove Letter. Dove Letter — это репозиторий с подпиской, где вы можете учиться, обсуждать и делиться новыми знаниями об Android и Kotlin. Если вы хотите присоединиться, обязательно ознакомьтесь со статьей «Изучайте Kotlin и Android с помощью Dove Letter».
Как структурировать модули в многомодульной архитектуре
Скорее всего, это одна из первых идей, которую вы рассматриваете, когда начинаете настраивать свой проект. Недавно на Dove Letter один из подписчиков задал интересный вопрос:
Подписчик представил на рассмотрение четыре различных шаблона модуляризации.
Шаблон 1
Начните с функционального модуля (папки) с именем onboarding
на корневом уровне. В этой папке создайте два отдельных модуля библиотеки Android: один для domain
, другой для presentation
.
Он структурирован таким образом, что основной модуль является отдельным, а внутри него есть отдельные подмодули для доменного и презентационного уровней.
Плюсы
Этот подход обеспечивает разделение ответственности по функциям, а также изолирует доменные и презентационные слои, что способствует созданию чистой архитектуры. Он поддерживает модульность, поощряя повторное использование логики домена и облегчая независимое тестирование по функциям и их доменам/представлениям. Кроме того, он обладает высокой масштабируемостью, что делает его подходящим для крупных проектов со сложными функциями. Поэтому, если ваша команда очень большая, каждая команда должна работать над разными фичами, и каждая проблема должна быть разделена, этот паттерн может стать отличным выбором.
Минусы
Однако он может увеличить сложность проекта при наличии множества модулей. Управление зависимостями между этими модулями также может быть сложным, что потенциально может привести к взаимозависимостям, требующим тщательной обработки. Особенно важно быть осторожным с потенциальными циклическими зависимостями в этой архитектуре. Если возникают циклы зависимостей, они могут сделать проект трудноуправляемым. Кроме того, поддержание такой структуры требует строгого соблюдения правил всеми членами команды, что может быть сложным и ресурсоемким, что звучит очень дорого.
Шаблон 2
Создайте единую библиотеку features
на корневом уровне. Затем добавьте все отдельные функции в виде отдельных библиотек внутри модуля features
.
Этот паттерн предполагает объединение всего в один фиче-модуль. Звучит очень просто!
Плюсы
Это очень просто. Легче управлять и менее сложно. Если вы считаете, что создаете просто домашний проект или в нем не будет задействовано более 1~2 разработчиков, этот паттерн может стать хорошим выбором. Иногда простота — это лучшее!
Минусы
Этот паттерн предлагает простоту и более легкое управление благодаря своей менее сложной структуре. Несмотря на то, что он позволяет в некоторой степени использовать модульный подход, когда функции изолированы в рамках одного модуля, он имеет ограничения по масштабируемости по мере роста проекта. Кроме того, доменные и презентационные слои не изолированы, что может привести к проблемам с поддержанием чистоты архитектуры по мере усложнения проекта.
Шаблон 3
Начните с функционального модуля (библиотеки Android) под названием onboarding
. Внутри этого модуля создайте два дополнительных модуля библиотеки Android: один для domain
и другой для presentation
.
Похоже, что фиче-модули более вложенные, чем в Шаблоне 1, и моя моя оценка такая же, как и в Шаблоне 1.
Шаблон 4
Создайте папку feature
на корневом уровне, а затем создайте отдельный библиотечный модуль для каждой фичи. Например, если у вас есть библиотечный модуль auth
в папке feature
, то организуйте его, создав подпапки для DI, Domain и Presentation в библиотечном модуле auth
.
Этот паттерн хорошо подходит для большинства проектов, особенно если ваша команда среднего размера (10~30 инженеров) и не требует высокой масштабируемости, необходимой для команд из 50-100 инженеров. В качестве альтернативы можно создать отдельные доменные и презентационные модули на корневом уровне, что позволит четко разделить ответственность в кодовой базе. Такой подход хорошо согласуется с принципами «чистой архитектуры», которая популярна для поддержания структурированной и поддерживаемой кодовой базы.
Плюсы
Паттерн упрощает структуру, сочетая простоту с модульностью, где каждая функция инкапсулируется в один модуль с внутренним разделением. Он управляем и прост в навигации, что делает его идеальным для средних проектов.
Минусы
Однако паттерн имеет ограниченную изоляцию, поскольку доменные и презентационные слои физически не разделены на отдельные модули, что может снизить гибкость. Кроме того, он менее масштабируем по сравнению с архитектурами, в которых для каждого слоя используются совершенно отдельные модули. Поэтому если вы отделите доменные и презентационные слои в независимый модуль, это будет лучший выбор, чем данный паттерн.
Подведем итоги
- Паттерн 1 и паттерн 3 лучше всего подходят для крупных, сложных проектов, требующих четкого разделения и масштабируемости.
- Шаблон 4 подходит для средних проектов, где простота является ключевым фактором, но некоторая модульность все же желательна.
- Шаблон 2 лучше всего подходит для небольших проектов, где простота и скорость более важны, чем строгое следование архитектурным принципам. Если вы работаете в команде, чтобы быстро создать проект для проверки реализуемости вашего бизнес MVP, выберите этот паттерн, а не тратьте много времени на создание сотен ненужных модулей.
Заключение
Мы рассмотрели четыре различных паттерна модуляризации для конфигурации вашего проекта с многомодульной архитектурой, а также плюсы и минусы каждого подхода. Как вы, вероятно, поняли, наилучший способ структурирования архитектуры вашего проекта в значительной степени зависит от его сложности и потребностей в масштабируемости — универсального решения не существует. Каждый проект имеет уникальные требования, и понимание этих требований имеет решающее значение для выбора наиболее подходящего архитектурного паттерна.
Если у вас есть вопросы или отзывы по этой статье, вы можете найти автора в Twitter @github_skydoves или на GitHub. Если вы хотите получать самую свежую информацию в виде статей и ссылок, советов с примерами кода, демонстрирующими лучшие практики, и новостей об экосистеме Android/Kotlin в целом, посмотрите «Изучайте Kotlin и Android с Dove Letter».
Как всегда, счастливого кодинга!