Проект с несколькими модулями Gradle известен как многомодульный проект (multi-module project). В этом официальном руководстве Google представлены передовые методы и рекомендуемые шаблоны для разработки многомодульных приложений для Android.
Проблема растущей кодовой базы
В постоянно растущей кодовой базе масштабируемость, удобочитаемость и общее качество кода часто со временем ухудшаются. Это происходит из-за того, что кодовая база увеличивается в размере, а ее сопровождающие не предпринимают активных действий для обеспечения структуры, которую легко поддерживать. Модульность — это средство структурирования вашей кодовой базы таким образом, чтобы улучшить удобство сопровождения и помочь избежать этих проблем.
Что такое модуляризация?
Модульность — это практика разделения кодовой базы на слабо связанные и автономные части. Каждая часть представляет собой модуль. Каждый модуль независим и служит определенной цели. Разделяя проблему на более мелкие и легко решаемые подзадачи, вы снижаете сложность проектирования и обслуживания большой системы.
Преимущества модульности
Преимуществ модульности много, хотя каждое из них сосредоточено на повышении удобства сопровождения и общего качества кодовой базы. В таблице ниже приведены основные преимущества.
- Возможность повторного использования
Модульность открывает возможности для совместного использования кода и создания нескольких приложений на одной основе. Модули фактически являются строительными блоками. Приложения должны представлять собой сумму своих функций, где функции организованы в виде отдельных модулей. Функциональность, предоставляемая определенным модулем, может быть включена или отключена в конкретном приложении. Например, :feature:news может быть частью полной версии приложения, но не частью демо-версии. - Строгий контроль видимости
Модули позволяют вам легко контролировать то, что вы предоставляете другим частям вашей кодовой базы. Вы можете пометить все, кроме общедоступного интерфейса, как internal или private, чтобы предотвратить использование вне модуля. - Настраиваемая доставка
Play Feature Delivery использует расширенные возможности пакетов приложений, позволяя вам предоставлять определенные функции вашего приложения на условиях или по запросу.
Вышеуказанные преимущества достижимы только при использовании модульной кодовой базы. Следующие преимущества могут быть достигнуты с помощью других методов, но модульность может помочь вам усилить их еще больше.
- Масштабируемость
В сильно связанной кодовой базе одно изменение может вызвать каскад изменений в, казалось бы, несвязанных частях кода. Надлежащим образом сделанный модульный проект будет реализовывать принцип разделения задач и, следовательно, ограничивать взаимосвязь разных частей. Это расширяет возможности участников за счет большей автономии. - Владение
Помимо предоставления автономии, модули также могут использоваться для обеспечения отчетности. У модуля может быть выделенный владелец, который отвечает за поддержку кода, исправление ошибок, добавление тестов и проверку изменений. - Инкапсуляция
Инкапсуляция означает, что каждая часть вашего кода должна иметь минимально возможное количество знаний о других частях. Изолированный код легче читать и понимать. - Тестируемость
Тестируемость характеризует простоту тестирования вашего кода. Тестируемый код — это код, компоненты которого можно легко протестировать изолированно. - Время сборки
Некоторые функции Gradle, такие как инкрементная сборка, кеш сборки или параллельная сборка, могут использовать модульность для повышения производительности сборки.
Распространенные ошибки
Степень детализации — это степень, в которой кодовая база состоит из модулей. Более гранулированная кодовая база имеет больше модулей меньшего размера. При разработке модульной кодовой базы следует определиться с уровнем детализации. Для этого примите во внимание размер вашей кодовой базы и ее относительную сложность. Излишняя детализация сделает накладные расходы тяжелым бременем, а слишком крупная уменьшит преимущества модульности.
Некоторые распространенные ловушки заключаются в следующем:
- Слишком мелкие модули: Каждый модуль вызывает определенные накладные расходы в виде повышенной сложности сборки и увеличения boilerplate кода. Сложная конфигурация сборки затрудняет поддержание согласованности конфигураций между модулями. Слишком большой объем шаблонного кода приводит к громоздкой кодовой базе, которую трудно поддерживать. Если накладные расходы мешают улучшениям масштабируемости, следует рассмотреть возможность консолидации некоторых модулей.
- Слишком большие модули: И наоборот, если ваши модули становятся слишком большими, вы можете получить еще один монолит и упустить преимущества, которые может предложить модульность. Например, в небольшом проекте можно поместить слой данных в один модуль. Но по мере роста может возникнуть необходимость разделить репозитории и источники данных на отдельные модули.
- Излишняя сложность: Не всегда имеет смысл разбивать проект на модули. Доминирующим фактором является размер кодовой базы. Если вы не ожидаете, что ваш проект превысит определенный порог, масштабируемость и выигрыш во времени сборки не дают преимуществ.
Подходит ли мне модульность?
Если вам нужны преимущества повторного использования кода, строгий контроль видимости или использование Play Feature Delivery, вам необходима модульность. Если вам это не нужно, но все же вы хотите получить выгоду от улучшенной масштабируемости, владения, инкапсуляции или времени сборки, то вам все равно стоит подумать о модульности.
Пример
Now in Android — полнофункциональное Android-приложение с модульностью.