Waarom modulariseren
Bouwsnelheid, eigenaarschap en hergebruik.
Waarom modulariseren is een gratis Android Academy-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Android Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Android Academy bevat in totaal 4 lessen.
Het monolietprobleem
Wanneer een Android-app groeit, staat alle code vaak in één app-module. Dit is een monoliet. In het begin is dat handig, maar na verloop van tijd wordt het lastig: elke wijziging raakt dezelfde module, builds worden traag en teamleden werken elkaar voortdurend in de weg.
Modularisatie betekent dat je die ene grote module opsplitst in veel kleinere, gerichte Gradle-modules. In deze les leer je waarom teams dit doen en welke concrete voordelen het oplevert.
Wat een module eigenlijk is
In Gradle is een module een zelfstandig te bouwen code-eenheid met een eigen build.gradle.kts-bestand. Je app heeft er al minstens één: de :app-module. Je declareert elke module in settings.gradle.kts.
Een module toevoegen is zo eenvoudig als deze opnemen. Elke module produceert zijn eigen builduitvoer en kan afhankelijk zijn van andere modules.
// settings.gradle.kts
include(":app")
include(":core:designsystem")
include(":core:data")
include(":feature:home")
include(":feature:profile")Voordeel 1: snellere builds
De grootste praktische winst is buildsnelheid. Gradle kan modules parallel bouwen en, nog belangrijker, modules waarvan de invoer niet is gewijzigd cachen en overslaan.
Als je alleen :feature:profile bewerkt, hergebruikt Gradle de al gebouwde uitvoer van elke andere module. In een monoliet kan elke wijziging een volledige hercompilatie van de app afdwingen.
- Parallelle uitvoering over modules heen
- Incrementele builds: bouw alleen opnieuw wat is gewijzigd
- Betere treffers in de externe buildcache
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=trueVoordeel 2: duidelijke grenzen
Modules dwingen grenzen af. Code in de ene module kan alleen zien wat een andere module bewust beschikbaar maakt. Zo voorkom je de verstrengelde spaghetti waarbij elke klasse in elke andere klasse kan grijpen.
Je beheert de zichtbaarheid met de Gradle-configuraties api en implementation. implementation houdt een afhankelijkheid privé binnen de module; gebruikers van de module kunnen deze niet per ongeluk gebruiken.
// feature/profile/build.gradle.kts
dependencies {
// Exposed to whoever depends on :feature:profile
api(project(":core:model"))
// Private: hidden from consumers of this module
implementation(project(":core:network"))
}Voordeel 3: hergebruik
Zodra logica in een gerichte module staat, kun je deze overal hergebruiken. Een :core:designsystem-module met je thema, kleuren en herbruikbare composables kan door elke functie worden gedeeld.
Hetzelfde idee werkt voor meerdere apps: een bedrijf kan een :core:network-module delen tussen verschillende producten in plaats van code te kopiëren.
// Any feature can pull in shared building blocks
// feature/home/build.gradle.kts
dependencies {
implementation(project(":core:designsystem"))
implementation(project(":core:data"))
}Voordeel 4: eigenaarschap van teams
Modules sluiten goed aan bij eigenaarschap van teams. Het betalingsteam beheert :feature:payments; het profielteam beheert :feature:profile. Ze kunnen parallel werken met minder samenvoegingsconflicten, omdat hun code in afzonderlijke mappen en buildbestanden staat.
Hulpmiddelen zoals een CODEOWNERS-bestand kunnen automatisch beoordelingen aanvragen bij het juiste team op basis van het modulepad.
# .github/CODEOWNERS
/feature/payments/ @org/payments-team
/feature/profile/ @org/profile-team
/core/designsystem/ @org/platform-teamVoordeel 5: inkapseling via zichtbaarheid
Binnen een module wordt Kotlin's internal-modifier krachtig. Een internal-klasse of -functie is alleen binnen de eigen module zichtbaar. Andere modules kunnen er letterlijk niet naar verwijzen.
Zo kun je een klein openbaar oppervlak beschikbaar maken en de implementatiedetails verbergen; iets wat je in één gigantische module niet kunt afdwingen.
// In :core:data
// Public API other modules may use
fun interface UserRepository {
suspend fun loadUser(id: String): User
}
// Hidden from other modules
internal class DefaultUserRepository(
private val api: UserApi
) : UserRepository {
override suspend fun loadUser(id: String) = api.fetch(id).toUser()
}De kosten: enige overhead
Modularisatie is niet gratis. Elke module voegt een te onderhouden build.gradle.kts toe en je moet bedenken welke module eigenaar is van elk stukje code. Te veel modulariseren in een kleine app zorgt voor extra werk zonder voordeel.
Vuistregel: modulariseer wanneer builds te lang duren, wanneer teams elkaar in de weg zitten of wanneer je duidelijke herbruikbare lagen hebt. Een hobby-app die je in het weekend bouwt, heeft zelden 30 modules nodig.
Een typische module-indeling
Een veelgebruikte, schaalbare structuur splitst modules op in de lagen app, feature en core. De :app-module verbindt alles; functies bevatten schermen voor gebruikers; core-modules bevatten gedeelde infrastructuur.
// Conceptual project tree
// app/ <- single entry point, wires features
// feature/
// home/
// profile/
// settings/
// core/
// designsystem/ <- theme + reusable composables
// data/ <- repositories
// network/ <- Retrofit/Ktor
// model/ <- shared data classesConventieplugins houden het beheersbaar
Met veel modules is overal dezelfde Gradle-configuratie kopiëren en plakken een valkuil. Teams halen gedeelde configuratie naar conventieplugins (in een build-logic-module). Elke echte module past vervolgens één plugin toe in plaats van tientallen regels te herhalen.
Je ziet dit patroon in grote opensource-apps zoals Now in Android. Onthoud voor nu alleen het doel: houd buildbestanden klein en consistent.
// feature/home/build.gradle.kts
plugins {
// One convention plugin sets up Android + Compose + Kotlin
id("myapp.android.feature")
}
android { namespace = "com.myapp.feature.home" }Mindset: denk in lagen
Het nuttigste mentale model is dat afhankelijkheden naar beneden moeten stromen. Functies zijn afhankelijk van core; core is niet afhankelijk van functies. De :app-module staat helemaal bovenaan en is afhankelijk van alles wat nodig is om de app samen te stellen.
Als je deze richting consistent aanhoudt, blijft je modulegrafiek overzichtelijk en voorkom je cycli, die je in een latere les zult onderzoeken.
// Allowed: app -> feature -> core
// Forbidden: core -> feature (upward) or feature -> feature (sideways)
// app/build.gradle.kts
dependencies {
implementation(project(":feature:home"))
implementation(project(":feature:profile"))
}Korte controle
Welke van de volgende opties is het meest concrete, dagelijkse voordeel dat teams halen uit het modulariseren van een groeiende Android-app?
Samenvatting: waarom modulariseren
Je hebt geleerd waarom teams een monoliet opsplitsen in modules:
- Snellere builds door parallelle uitvoering en incrementeel cachen
- Duidelijke grenzen met
api/implementationeninternal - Hergebruik van core-lagen zoals het designsysteem en netwerk
- Eigenaarschap van teams met minder samenvoegingsconflicten
Je hebt ook de kosten gezien (extra buildbestanden) en de gouden regel: afhankelijkheden stromen naar beneden, app -> feature -> core. Vervolgens ga je de daadwerkelijke grenzen tussen feature- en core-modules tekenen.
Leer Kotlin met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 36
- Lessen
- 152
Veelgestelde vragen
Is de les “Waarom modulariseren” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Android Academy, waaronder “Waarom modulariseren”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Android Academy bevat in totaal 4 lessen.
Wat leer ik in “Waarom modulariseren”?
Bouwsnelheid, eigenaarschap en hergebruik. Je oefent met Android Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Android Academy te beginnen?
Ervaring vooraf is niet nodig. Android Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Waarom modulariseren”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Android Academy?
Ja. Elke les over Android Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Waarom modulariseren
- Feature- en coremodules
- Moduleafhankelijkheden beheren
- Navigatie tussen modules