0Pricing
Android Academy · Lezione

Perché modularizzare

Velocità di build, responsabilità e riutilizzo

Perché modularizzare è una lezione Android Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Android Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Android Academy include 4 lezioni in totale.

Il problema del monolite

Quando un'app Android cresce, spesso tutto il codice finisce in un unico modulo app. Questo è un monolite. All'inizio è comodo, ma con il tempo diventa problematico: ogni modifica coinvolge lo stesso modulo, le build diventano lente e i membri del team si intralciano continuamente.

La modularizzazione consiste nel dividere quel grande modulo in molti moduli Gradle più piccoli e focalizzati. In questa lezione imparerà perché i team adottano questo approccio e quali vantaggi concreti offre.

Che cos'è effettivamente un modulo

In Gradle, un modulo è un'unità di codice compilabile indipendentemente, con il proprio file build.gradle.kts. L'app ne possiede già almeno uno: il modulo :app. Ogni modulo viene dichiarato in settings.gradle.kts.

Aggiungere un modulo è semplice quanto includerlo. Ogni modulo produce il proprio output di build e può dipendere da altri moduli.

// settings.gradle.kts
include(":app")
include(":core:designsystem")
include(":core:data")
include(":feature:home")
include(":feature:profile")

Vantaggio 1: build più veloci

Il vantaggio pratico più importante è la velocità della build. Gradle può compilare i moduli in parallelo e, soprattutto, può memorizzare nella cache e saltare i moduli i cui input non sono cambiati.

Se modifica solo :feature:profile, Gradle riutilizza gli output già compilati di tutti gli altri moduli. In un monolite, qualsiasi modifica può obbligare a ricompilare l'intera app.

  • Esecuzione parallela tra i moduli
  • Build incrementali: viene ricompilato solo ciò che è cambiato
  • Percentuali migliori di utilizzo della cache remota e della build cache
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true

Vantaggio 2: confini chiari

I moduli impongono confini. Il codice di un modulo può vedere solo ciò che un altro modulo espone esplicitamente. Questo impedisce di creare una rete intricata in cui ogni classe accede direttamente a tutte le altre.

La visibilità viene controllata con le configurazioni Gradle api e implementation. implementation mantiene privata la dipendenza all'interno del modulo; i consumer non possono utilizzarla accidentalmente.

// 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"))
}

Vantaggio 3: riutilizzo

Quando la logica risiede in un modulo focalizzato, è possibile riutilizzarla ovunque. Un modulo :core:designsystem che contiene il tema, i colori e i composable riutilizzabili può essere condiviso da ogni funzionalità.

Lo stesso principio si applica a più app: un'azienda può condividere un modulo :core:network tra diversi prodotti invece di copiare il codice.

// Any feature can pull in shared building blocks
// feature/home/build.gradle.kts
dependencies {
    implementation(project(":core:designsystem"))
    implementation(project(":core:data"))
}

Vantaggio 4: responsabilità del team

I moduli corrispondono naturalmente alla responsabilità del team. Il team pagamenti gestisce :feature:payments; il team profilo gestisce :feature:profile. I team possono lavorare in parallelo con meno conflitti di merge, perché il codice si trova in cartelle e file di build separati.

Strumenti come un file CODEOWNERS possono richiedere automaticamente le revisioni al team appropriato in base al percorso del modulo.

# .github/CODEOWNERS
/feature/payments/   @org/payments-team
/feature/profile/    @org/profile-team
/core/designsystem/  @org/platform-team

Vantaggio 5: incapsulamento tramite la visibilità

All'interno di un modulo, il modificatore internal di Kotlin diventa molto potente. Una classe o una funzione internal è visibile solo all'interno del proprio modulo. Gli altri moduli non possono farvi riferimento.

In questo modo è possibile esporre una superficie pubblica ridotta e nascondere i dettagli di implementazione, cosa che non è possibile imporre in un unico modulo di grandi dimensioni.

// 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()
}

Il costo: un certo sovraccarico

La modularizzazione non è gratuita. Ogni modulo aggiunge un file build.gradle.kts da gestire e occorre decidere quale modulo sia responsabile di ogni parte del codice. Modularizzare eccessivamente un'app piccola crea lavoro inutile senza vantaggi.

La regola generale è: modularizzi quando i tempi di build diventano un problema, quando i team entrano in conflitto o quando disponi di livelli chiaramente riutilizzabili. Un'app amatoriale sviluppata nel fine settimana raramente ha bisogno di 30 moduli.

Una struttura tipica dei moduli

Una struttura comune e scalabile divide i moduli nei livelli app, feature e core. Il modulo :app collega tutti gli elementi; le feature contengono le schermate rivolte agli utenti; i moduli core contengono l'infrastruttura condivisa.

// 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 classes

I convention plugin mantengono l'ordine

Con molti moduli, copiare e incollare la stessa configurazione Gradle ovunque è una trappola. I team estraggono la configurazione condivisa in convention plugin (all'interno di un modulo build-logic). Ogni modulo effettivo applica quindi un solo plugin invece di ripetere decine di righe.

Vedrà questo modello in grandi app open source come Now in Android. Per ora è sufficiente conoscerne l'obiettivo: mantenere i file di build brevi e coerenti.

// feature/home/build.gradle.kts
plugins {
    // One convention plugin sets up Android + Compose + Kotlin
    id("myapp.android.feature")
}

android { namespace = "com.myapp.feature.home" }

Mentalità: pensare per livelli

Il modello mentale più utile è questo: le dipendenze devono fluire verso il basso. Le feature dipendono dal core; il core non dipende dalle feature. Il modulo :app si trova in cima e dipende da tutto ciò che gli serve per assemblare l'app.

Se mantiene coerente questa direzione, il grafo dei moduli rimane ordinato e si evitano i cicli, che verranno analizzati in una lezione successiva.

// 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"))
}

Verifica rapida

Qual è il vantaggio più concreto e quotidiano che i team ottengono modularizzando un'app Android in crescita?

Riepilogo: perché modularizzare

Ha imparato perché i team suddividono un monolite in moduli:

  • Build più veloci grazie all'esecuzione parallela e alla memorizzazione incrementale nella cache
  • Confini chiari tramite api/implementation e internal
  • Riutilizzo dei livelli core, come il design system e la rete
  • Responsabilità del team con meno conflitti di merge

Ha anche visto il costo, ovvero file di build aggiuntivi, e la regola d'oro: le dipendenze fluiscono verso il basso, app -> feature -> core. Nella prossima lezione traccerà i confini effettivi tra i moduli feature e core.

Domande Frequenti

La lezione «Perché modularizzare» è gratuita?

Sì — il testo completo di «Perché modularizzare» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Android Academy, passa a CoddyKit PRO. Il corso Android Academy include 4 lezioni in totale.

Cosa imparerò in «Perché modularizzare»?

Velocità di build, responsabilità e riutilizzo Eserciti Android Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Android Academy?

Non è richiesta alcuna esperienza precedente. Android Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Perché modularizzare»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Android Academy?

Sì. Ogni lezione Android Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Perché modularizzare
  2. Moduli feature e core
  3. Gestire le dipendenze tra moduli
  4. Navigazione tra moduli
← Torna a Android Academy