Модульність у мобільній розробці — суть, принципи та організація

Автор: IT Sectr Опубліковано: 2026-05-13 Час читання: 9 хв

Модульність — це принцип, за якого застосунок збирається з незалежних модулів, кожен із яких відповідає за одну функціональність. За даними Android Developers, поділ на модулі прискорює збірку завдяки паралельній компіляції та дозволяє командам працювати над різними частинами застосунку незалежно. Модульна архітектура стала стандартом для великих мобільних проєктів із десятками розробників.

Головне

  • Модульність — розбиття застосунку на незалежні блоки з чіткими межами та інтерфейсами
  • Модулі Gradle в Android та Swift Packages в iOS — основні інструменти модульної архітектури
  • Ізоляція коду в модулях запобігає випадковим залежностям між непов'язаними функціями
  • Паралельна збірка модулів скорочує час компіляції в 2–4 рази на великих проєктах
  • Feature-first — найпопулярніший підхід, за якого кожен екран або функція виділені в окремий модуль

Що таке модульність у мобільній розробці

Модульність — це спосіб організації коду, за якого застосунок складається зі слабко зв'язаних модулів, кожен із яких надає строго визначену функціональність через публічний інтерфейс. На відміну від монолітної архітектури, де всі класи знаходяться в одному проєкті, модульний підхід розділяє код на фізично незалежні одиниці збірки.

Основна мета модульності — управління складністю. Розробник може зосередитися на одному модулі, не тримаючи в голові всю кодову базу. Кожен модуль має свою зону відповідальності та може розроблятися, тестуватися і розгортатися незалежно від інших. Це особливо цінно в проєктах із 10+ розробниками, де паралельна робота над монолітом призводить до частих конфліктів злиття.

Важливо відрізняти модульність від шаруватої архітектури. Шари (Presentation, Domain, Data) ділять код за технічною ознакою, а модулі — за функціональною. Модуль «Профіль користувача» може містити власні шари всередині. На практиці модульний підхід і шарувата архітектура комбінуються: кожен модуль має власну тришарову структуру.

Види модулів та їх призначення

Feature-модулі — найпопулярніший вид модулів. Кожен екран або група пов'язаних екранів виділяється в окремий модуль: Onboarding, Profile, Settings, Feed. Feature-модуль містить все необхідне для роботи функції: UI, бізнес-логіку, data-шар. Межі модуля захищені — інші функції не можуть отримати доступ до його внутрішніх класів.

Core-модулі містять загальну інфраструктуру: роботу з мережею, базою даних, аналітикою, дизайн-системою. Вони не залежать від feature-модулів, але feature-модулі залежать від них. Такий поділ гарантує, що зміна аналітичного SDK не вплине на мережевий шар, і навпаки. Core-модулі повторно використовуються між фічами без дублювання коду.

Shared модулі для спільної логіки

Shared-модулі містять код, який використовується кількома фічами: моделі даних, утиліти, константи, кастомні View. Основна проблема shared-модулів — ризик перетворення на звалище («misc module»), де з часом накопичується різнорідний код. Правило: shared-модуль повинен мати чітку тематику, наприклад «shared-ui» або «shared-models».

В Android shared-модулі часто виділяють у бібліотеки з префіксом lib: lib-network, lib-database, lib-ui-components. В iOS ті ж функції виконують внутрішні Swift Packages всередині Workspace. На практиці команди обмежують кількість shared-модулів 3–5, щоб не створювати надмірну мережу залежностей, що ускладнює збірку.

Test-модулі та ізоляція тестування

Окремі test-модулі дозволяють запускати тести лише для зміненого модуля, не прогоняючи всю тестову базу. Це скорочує час CI/CD пайплайну з годин до хвилин. Модульна ізоляція забезпечує SoC на рівні збірки: модуль мережевого шару не може випадково імпортувати UI-бібліотеки у своїх тестах.

Кожен модуль повинен мати чітко визначений публічний API. В Android це досягається через access modifiers та api vs implementation в Gradle. В iOS — через public/internal модифікатори доступу та керовані залежності через Package.swift. Скорочення видимості до мінімально необхідної — ключова практика модульного дизайну.

Модульність в Android: Gradle modules

Gradle підтримує модульну архітектуру нативно: кожен модуль — це окрема одиниця збірки зі своїм build.gradle файлом. Android проєкти використовують комбінацію application модуля (app) та кількох library модулів. Бібліотечні модулі не можуть бути запущені як застосунок, але можуть публікуватися як AAR в репозиторій.

Ключова фіча Gradle — паралельна збірка незалежних модулів. Якщо modules A, B та C не залежать один від одного, Gradle компілює їх одночасно, використовуючи всі ядра процесора. У проєктах із 20+ модулями це скорочує повну збірку з 15 до 3–5 хвилин. Інкрементальна збірка зміненого модуля займає секунди.

Gradle надає два типи залежностей між модулями: api (транзитивні) та implementation (нетранзитивні). Різниця критично важлива для модульності: implementation приховує транзитивні залежності від споживачів модуля. Якщо модуль :profile використовує :networking через implementation, споживачі :profile не знають про :networking і не можуть до нього звернутися.

groovy
// settings.gradle — декларація модулів
include ':app'
include ':feature:profile'
include ':feature:settings'
include ':core:network'
include ':core:database'

// build.gradle feature/profile — залежності модуля
dependencies {
    implementation project(':core:network')
    implementation project(':core:database')
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0'
}

Код показує структуру модульного Android-проєкту. Settings.gradle перелічує всі модулі, а build.gradle кожного feature-модуля вказує лише ті core-модулі, які йому потрібні. Build system автоматично розв'язує транзитивні залежності та збирає модулі в правильному порядку.

Модульність в iOS: Swift Package Manager та CocoaPods

Swift Package Manager (SPM) — стандартний інструмент модульності в iOS з 2019 року. SPM дозволяє розбивати застосунок на Swift Packages, кожен із яких може бути library або executable. Package визначає модулі (targets) та їх залежності через Package.swift. SPM інтегрований в Xcode і не потребує додаткових інструментів.

CocoaPods залишається основним менеджером залежностей для сторонніх бібліотек. Podfile та Podspec задають модульну структуру, а CocoaPods генерує workspace з окремими pod-проєктами. Для власної модульності проєкту команди все частіше обирають SPM, оскільки він вбудований в Xcode і не потребує встановлення.

В iOS модульності важливу роль відіграє access control: public, package, internal, fileprivate та private. Модуль публікує лише ті типи, які мають бути доступні іншим модулям. Внутрішні деталі реалізації приховані за internal та private модифікаторами. Це запобігає появі прихованих залежностей між модулями.

swift
// Package.swift — модульна структура iOS проєкту
let package = Package(
    name: "MyApp",
    platforms: [.iOS(SupportedPlatform.iOSVersion.v17)],
    products: [
        .library(name: "ProfileFeature", targets: ["ProfileFeature"]),
        .library(name: "NetworkCore", targets: ["NetworkCore"]),
    ],
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0")
    ],
    targets: [
        .target(name: "ProfileFeature", dependencies: ["NetworkCore"]),
        .target(name: "NetworkCore", dependencies: ["Alamofire"]),
    ]
)

Package.swift оголошує два library-продукти: ProfileFeature та NetworkCore. ProfileFeature залежить від NetworkCore, але не знає про існування Alamofire — той прихований всередині NetworkCore. Така ізоляція — пряме застосування SoC на рівні модулів: зміни в HTTP-клієнті не потребують перекомпіляції ProfileFeature.

Переваги та складнощі модульної архітектури

Основна перевага модульності — швидкість розробки. Команди працюють паралельно над різними модулями без конфліктів у коді. CI/CD пайплайн збирає лише змінені модулі та запускає лише їх тести. Час фідбеку скорочується, а частота релізів зростає. Spotify, Uber та Airbnb публікували кейси міграції на модульну архітектуру з покращенням метрик у 2–3 рази.

Друга перевага — ізоляція помилок. Баг у модулі Profile не впливає на модуль Payments, якщо між ними немає прямих залежностей. Це особливо важливо в застосунках із високоризиковою функцією (платежі, медичні дані), де помилка в непов'язаному екрані не повинна блокувати реліз критичного функціоналу.

Головна складність — управління залежностями. При неправильному проєктуванні виникає граф модулів, де зміна одного модуля каскадно перезбирає десятки інших. Рішення — слідувати правилу ациклічності: граф залежностей модулів має бути спрямованим ациклічним графом (DAG). Інструменти на кшталт Gradle Module Graph Assert допомагають виявити цикли на етапі збірки.

Друга складність — зростання часу початкового налаштування. Створення модульної архітектури потребує більше часу на етапі ініціалізації проєкту. Невеликі проєкти з 1–3 розробниками можуть не отримати вигоди від модульності, витрачаючи час на підтримку меж модулів без реальної потреби в розпаралелюванні. Рішення — починати з моноліту та виділяти модулі в міру зростання команди.

Підходи Feature-first vs Layer-first

Feature-first підхід групує модулі за функціональністю: кожен екран або група екранів стає окремим модулем. Layer-first підхід ділить код за технічною ознакою: окремі модулі для UI, бізнес-логіки та даних. На практиці більшість команд обирають feature-first з core-модулями — це дає кращу ізоляцію та зрозумілу навігацію по проєкту.

Вибір між підходами залежить від розміру команди та передбачуваності функціональності. Якщо ви точно знаєте, які екрани будуть у проєкті, feature-first дозволяє кожному розробнику відповідати за свій модуль. Якщо функціональність часто змінюється та перетинається між екранами, layer-first дає більше гнучкості при повторному використанні коду між різними фічами.

Часто задавані питання

Скільки модулів має бути в застосунку?

Оптимальна кількість залежить від розміру проєкту та команди. Для команди з 5 осіб достатньо 6–10 модулів. Для 20+ розробників — 20–40 модулів. Правило: модуль має бути достатньо малим, щоб один розробник розумів його цілком, і достатньо великим, щоб не створювати надмірну мережу залежностей.

Чи сповільнює модульність збірку?

Правильна модульність прискорює збірку завдяки паралельній компіляції та кешуванню. Але надмірна кількість модулів із щільними залежностями сповільнює збірку — Gradle та Xcode витрачають час на розв'язання графа. Ключ до швидкої збірки — мінімізація транзитивних залежностей та дотримання ациклічності.

Чи можна зробити модульним існуючий застосунок?

Так, але ітеративно. Почніть із виділення core-модулів (мережа, база даних), потім виносьте фічі по одній. Використовуйте feature flags, щоб вмикати новий модульний код паралельно зі старим монолітним. Повна міграція великого застосунку займає від 3 до 12 місяців.

Чим модульність відрізняється від мікросервісів?

Модулі — це одиниці компіляції всередині одного застосунку. Мікросервіси — окремі процеси, що працюють на різних серверах. Модулі розділяють код, мікросервіси розділяють runtime. У мобільній розробці часто використовується термін «microapps» як гібрид: feature-модулі, які можуть запускатися як самостійні застосунки.

Як тестувати модульний застосунок?

Кожен модуль має власні Unit-тести, що запускаються незалежно. Integration-тести перевіряють взаємодію між модулями. UI-тести покривають feature-модулі з mock-даними. Модульна архітектура спрощує тестування: замокати залежність іншого модуля простіше, ніж замокати частину моноліту.

Підсумки

  • Модульність — розбиття застосунку на незалежні одиниці збірки з чіткими межами
  • Feature-модулі групують код навколо функціональності, core-модулі — навколо інфраструктури
  • Gradle в Android та SPM в iOS — основні інструменти для реалізації модульної архітектури
  • Parallel build та ізоляція коду — головні переваги модульності у великих проєктах
  • Граф залежностей має бути ациклічним, інакше збірка сповільнюється та виникають циклічні посилання
  • Feature-first підхід з core-модулями визнано найбільш ефективним для великих мобільних проєктів
  • Починайте з моноліту та виділяйте модулі в міру зростання команди та кодової бази

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також