Feature- und Core-Module
Modulgrenzen festlegen
Feature- und Core-Module ist eine kostenlose Android Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Android Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.
Zwei Arten von Modulen
Die meisten modularisierten Android-Apps organisieren ihren Code in zwei Hauptarten von Modulen: Feature-Module und Core-Module sowie ein schlankes :app-Modul an der Spitze.
- Feature-Module enthalten einen benutzerorientierten Teil der App (einen Bildschirm oder Ablauf).
- Core-Module enthalten gemeinsam genutzte Infrastruktur, die von vielen Features verwendet wird.
In dieser Lektion lernen Sie, wie Sie diese Grenzen sinnvoll festlegen.
Aufbau eines Feature-Moduls
Ein Feature-Modul wie :feature:profile enthält alles, was ein einzelnes Feature benötigt: seine Compose-Bildschirme, sein ViewModel und seinen UI-Zustand. Es ist vertikal aufgebaut: Es umfasst den vollständigen Bereich von der UI bis zu seinem ViewModel.
Es hängt für gemeinsam genutzte Bestandteile von Core-Modulen ab, sollte jedoch nicht von anderen Feature-Modulen abhängen.
// 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()
}
}Das Feature-ViewModel
Jedes Feature besitzt sein eigenes ViewModel. Es ruft Daten über ein Repository aus einem Core-Modul ab und stellt den UI-Zustand bereit. Das Feature-Modul weiß nicht, wie die Daten abgerufen werden, sondern kennt nur den Repository-Vertrag.
// 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)
}Aufbau eines Core-Moduls
Ein Core-Modul ist horizontal aufgebaut: Es stellt eine Fähigkeit bereit, die in mehreren Features verwendet wird. Häufige Core-Module sind:
:core:model— einfache Datenklassen, die überall gemeinsam genutzt werden:core:network— Retrofit-/Ktor-Clients:core:database— Room-Konfiguration:core:data— Repositories, die Netzwerk und Datenbank kombinieren:core:designsystem— Theme und wiederverwendbare Composables
// core/model/User.kt
data class User(
val id: String,
val name: String,
val avatarUrl: String
)Das Designsystem-Modul
:core:designsystem ist eines der am häufigsten wiederverwendeten Module. Es enthält Ihr MaterialTheme, Farbschemata, Typografie und wiederverwendbare Composables wie Schaltflächen und Karten. Jedes Feature verwendet dasselbe Erscheinungsbild, ohne Code zu kopieren.
// 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
)
}Das Datenmodul verwaltet Repositories
Das Modul :core:data stellt Repository-Schnittstellen bereit, von denen Features abhängen, und verbirgt gleichzeitig die Implementierung. Es hängt normalerweise von :core:network und :core:database ab und führt beide zu einer einzigen Quelle der Wahrheit zusammen.
// 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()) }
}Model und Designsystem schlank halten
Die Module auf der untersten Ebene sollten von möglichst wenig abhängen. :core:model sollte idealerweise überhaupt keine Android-Abhängigkeiten haben – nur einfache Kotlin-Datenklassen. Dadurch kann es überall verwendet werden und lässt sich schnell bauen.
Wenn :core:model von Retrofit oder Room abhängen würde, würde jedes Modul, das Ihre Datenklassen verwendet, diese umfangreichen Bibliotheken mit einbinden.
// core/model/build.gradle.kts
plugins {
id("myapp.jvm.library") // pure Kotlin, no Android
}
// No Retrofit, no Room, no Compose here — just data classesDas schlanke :app-Modul
Das :app-Modul ist der Assembler. Es sollte nur sehr wenig Logik enthalten: die Application-Klasse, die einzelne MainActivity, den übergeordneten NavHost und die Verdrahtung der Dependency Injection. Alle echten Screens befinden sich in Feature-Modulen.
Ein schlankes App-Modul bedeutet, dass die meisten Änderungen in den Features stattfinden und das App-Modul daher nur selten neu gebaut werden muss.
// 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
}
}
}
}Gute Grenzen ziehen
Wie entscheiden Sie, was zu einem Modul wird? Einige praktische Faustregeln:
- Ein Feature ist ein Screen oder Ablauf, den ein Benutzer benennen kann (Startseite, Profil, Kasse).
- Ein Core-Modul ist eine Fähigkeit, die von mindestens zwei Features wiederverwendet wird.
- Wenn zwei Features denselben Code benötigen, verschieben Sie ihn nach unten in ein Core-Modul.
- Wenn ein Modul zu viele voneinander unabhängige Aufgaben übernimmt, teilen Sie es auf.
Optional: Aufteilung in api und impl
Große Apps teilen ein Feature manchmal in ein öffentliches :feature:profile:api (Schnittstellen, Navigationsrouten) und ein privates :feature:profile:impl (Screens, ViewModels) auf. Andere Features hängen nur vom kleinen api-Modul ab, niemals von der Implementierung.
Das ist fortgeschritten; für die meisten Apps ist ein einzelnes Modul pro Feature völlig ausreichend. Sie sollten aber wissen, dass es dieses Muster für sehr große Codebasen gibt.
// 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)
}Den Graphen zusammensetzen
So werden die Ebenen in unserem Beispiel miteinander verbunden. Beachten Sie, dass Abhängigkeiten immer nur nach unten zeigen: 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)Kurze Überprüfung
Ihre Module :feature:home und :feature:profile müssen beide Benutzerdaten abrufen und zwischenspeichern. Wo sollte der Repository-Code liegen?
Zusammenfassung: Feature- und Core-Module
Sie haben gelernt, Code in zwei Ebenen aufzuteilen:
- Feature-Module sind vertikale Ausschnitte (Screen + ViewModel + UI-Zustand).
- Core-Module sind horizontale Fähigkeiten (Model, Netzwerk, Datenbank, Daten, Designsystem).
- Das
:app-Modul bleibt schlank und setzt lediglich die Features zusammen. - Gemeinsam genutzter Code wandert nach unten in den Core;
:core:modelbleibt frei von Android-Abhängigkeiten und schlank.
Als Nächstes verwalten Sie die Abhängigkeiten zwischen diesen Modulen und halten den Graphen übersichtlich.
Häufig gestellte Fragen
Ist die Lektion „Feature- und Core-Module“ kostenlos?
Ja — der vollständige Text von „Feature- und Core-Module“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Android Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Feature- und Core-Module“?
Modulgrenzen festlegen Du übst Android Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Android Academy zu starten?
Keine Vorkenntnisse erforderlich. Android Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Feature- und Core-Module“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Android Academy-Lektion Code schreiben und ausführen?
Ja. Jede Android Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Warum modularisieren?
- Feature- und Core-Module
- Modulabhängigkeiten verwalten
- Navigation über Module hinweg