Moduli feature e core
Definisca i confini dei moduli
Moduli feature e core è una lezione Android Academy gratuita su CoddyKit. Questa è la lezione 2 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.
Due tipi di moduli
La maggior parte delle app Android modularizzate organizza il codice in due tipi principali di moduli: i moduli feature e i moduli core, oltre a un modulo :app sottile al livello superiore.
- I moduli feature contengono una parte dell'app rivolta all'utente, come una schermata o un flusso.
- I moduli core contengono l'infrastruttura condivisa utilizzata da molte feature.
In questa lezione imparerà a definire correttamente questi confini.
Anatomia di un modulo feature
Un modulo feature come :feature:profile contiene tutto ciò di cui ha bisogno una singola funzionalità: le schermate Compose, il proprio ViewModel e lo stato dell'interfaccia. È verticale: gestisce l'intero livello, dall'interfaccia fino al view-model.
Dipende dai moduli core per gli elementi condivisi, ma non dovrebbe dipendere da altri moduli feature.
// feature/profile/ProfileScreen.kt
@Composable
fun ProfileScreen(viewModel: ProfileViewModel = hiltViewModel()) {
val state by viewModel.uiState.collectAsStateWithLifecycle()
when (state) {
is ProfileUiState.Loading -> CircularProgressIndicator()
is ProfileUiState.Success -> ProfileContent((state as ProfileUiState.Success).user)
is ProfileUiState.Error -> ErrorMessage()
}
}Il ViewModel della feature
Ogni feature gestisce il proprio ViewModel. Recupera i dati tramite un repository di un modulo core ed espone lo stato dell'interfaccia. Il modulo feature non sa nulla di come vengono recuperati i dati, ma conosce solo il contratto del repository.
// feature/profile/ProfileViewModel.kt
@HiltViewModel
class ProfileViewModel @Inject constructor(
private val userRepository: UserRepository // from :core:data
) : ViewModel() {
val uiState: StateFlow<ProfileUiState> =
userRepository.observeUser()
.map { ProfileUiState.Success(it) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), ProfileUiState.Loading)
}Anatomia di un modulo core
Un modulo core è orizzontale: fornisce una capacità utilizzata da più feature. Tra i moduli core comuni vi sono:
:core:model— semplici classi di dati condivise ovunque:core:network— client Retrofit/Ktor:core:database— configurazione di Room:core:data— repository che combinano rete e database:core:designsystem— tema e composable riutilizzabili
// core/model/User.kt
data class User(
val id: String,
val name: String,
val avatarUrl: String
)Il modulo del design system
:core:designsystem è uno dei moduli più riutilizzati. Contiene il MaterialTheme, gli schemi di colore, la tipografia e composable riutilizzabili come pulsanti e schede. Ogni feature applica lo stesso aspetto senza copiare il codice.
// core/designsystem/AppTheme.kt
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) DarkColors else LightColors
MaterialTheme(
colorScheme = colors,
typography = AppTypography,
content = content
)
}Il modulo data gestisce i repository
Il modulo :core:data espone le interfacce dei repository da cui dipendono le feature, nascondendone l'implementazione. In genere dipende da :core:network e :core:database, combinandoli in un'unica fonte di verità.
// core/data/UserRepository.kt
interface UserRepository {
fun observeUser(): Flow<User>
suspend fun refresh()
}
// core/data/OfflineFirstUserRepository.kt
internal class OfflineFirstUserRepository @Inject constructor(
private val api: UserApi, // :core:network
private val dao: UserDao // :core:database
) : UserRepository {
override fun observeUser(): Flow<User> = dao.observe().map { it.toUser() }
override suspend fun refresh() { dao.upsert(api.fetch().toEntity()) }
}Mantenere leggeri model e designsystem
I moduli core di livello più basso dovrebbero dipendere dal minor numero possibile di elementi. Idealmente, :core:model non dovrebbe avere alcuna dipendenza da Android: solo semplici classi dati Kotlin. In questo modo può essere utilizzato ovunque e compilato rapidamente.
Se :core:model iniziasse a dipendere da Retrofit o Room, ogni modulo che utilizza le classi dati trascinerebbe con sé queste librerie pesanti.
// core/model/build.gradle.kts
plugins {
id("myapp.jvm.library") // pure Kotlin, no Android
}
// No Retrofit, no Room, no Compose here — just data classesIl modulo :app sottile
Il modulo :app è l'assemblatore. Dovrebbe contenere pochissima logica: la classe Application, l'unica MainActivity, il NavHost di livello superiore e la configurazione della dependency injection. Tutte le schermate reali risiedono nei moduli delle funzionalità.
Un modulo app sottile significa che la maggior parte delle modifiche avviene nelle funzionalità, quindi il modulo app viene ricompilato raramente.
// app/MainActivity.kt
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme { // from :core:designsystem
AppNavHost() // routes into :feature:* screens
}
}
}
}Definire buoni confini
Come si decide che cosa deve diventare un modulo? Ecco alcuni criteri pratici:
- Una funzionalità = una schermata o un flusso che l'utente può nominare (Home, Profile, Checkout).
- Un modulo core = una capacità riutilizzata da almeno 2 funzionalità.
- Se due funzionalità richiedono entrambe lo stesso codice, spostatelo verso il basso in un modulo core.
- Se un modulo svolge troppe attività non correlate, dividetelo.
Opzionale: separazione api e impl
Talvolta le app di grandi dimensioni dividono una funzionalità in un modulo pubblico :feature:profile:api (interfacce, route di navigazione) e in un modulo privato :feature:profile:impl (schermate, view-model). Le altre funzionalità dipendono solo dal piccolo modulo api, mai dall'implementazione.
Si tratta di una tecnica avanzata; per la maggior parte delle app è più che sufficiente un singolo modulo per funzionalità. È comunque utile sapere che questo schema esiste per i codebase molto grandi.
// Other features see only the contract, not the screens
// feature/home depends on :feature:profile:api
interface ProfileEntry {
val route: String
fun NavGraphBuilder.register(navController: NavController)
}Assemblare il grafo
Ecco come vengono collegati i livelli nel nostro esempio. Notate che le dipendenze puntano sempre verso il basso: app -> feature -> data -> network/database -> model.
// :app -> :feature:home, :feature:profile
// :feature:home -> :core:data, :core:designsystem
// :feature:profile -> :core:data, :core:designsystem
// :core:data -> :core:network, :core:database, :core:model
// :core:network -> :core:model
// :core:database -> :core:model
// :core:model -> (nothing)Verifica rapida
I moduli :feature:home e :feature:profile devono entrambi recuperare e memorizzare nella cache i dati dell'utente. Dove dovrebbe risiedere il codice del repository?
Riepilogo: moduli Feature e Core
Ha imparato a dividere il codice in due livelli:
- I moduli Feature sono sezioni verticali (schermata + ViewModel + stato dell'interfaccia).
- I moduli Core sono capacità orizzontali (model, network, database, data, designsystem).
- Il modulo
:apprimane sottile e si limita ad assemblare le funzionalità. - Il codice condiviso viene spostato verso il basso nel core;
:core:modelrimane privo di dipendenze Android e leggero.
Ora gestirà le dipendenze tra questi moduli e manterrà pulito il grafo.
Domande Frequenti
La lezione «Moduli feature e core» è gratuita?
Sì — il testo completo di «Moduli feature e core» è 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 «Moduli feature e core»?
Definisca i confini dei moduli 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 2 di 4.
Quanto tempo richiede la lezione «Moduli feature e core»?
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
- Perché modularizzare
- Moduli feature e core
- Gestire le dipendenze tra moduli
- Navigazione tra moduli