9.4 KiB
Client Common-UI Modul
Überblick
Das common-ui Modul stellt die geteilten Benutzeroberflächen-Komponenten und Geschäftslogik für die Meldestelle Client-Anwendungen bereit. Dieses Modul implementiert die Kern-"Tracer Bullet" Funktionalität unter Verwendung eines modernen MVVM-Architekturmusters und dient sowohl der Desktop- als auch der Web-Anwendung.
Hauptfunktionen:
- 🏗️ MVVM-Architektur - ordnungsgemäße Trennung der Belange mit ViewModel-Muster
- 🌐 Plattformübergreifend - geteilter Code für Desktop (JVM) und Web (JavaScript) Anwendungen
- 🎯 Vier UI-Zustände - vollständige Implementierung gemäß trace-bullet-guideline.md
- 🔧 Ressourcenverwaltung - ordnungsgemäßer HttpClient-Lebenszyklus und Speicherverwaltung
- 🧪 Testabdeckung - umfassende Testsuite für alle kritischen Funktionen
Architektur
Modulstruktur
client/common-ui/src/
├── commonMain/kotlin/at/mocode/client/
│ ├── data/service/
│ │ ├── PingResponse.kt # Datenmodell für API-Antworten
│ │ └── PingService.kt # HTTP-Service mit Ressourcenverwaltung
│ └── ui/
│ ├── App.kt # Hauptanwendungskomponente
│ └── viewmodel/
│ └── PingViewModel.kt # MVVM-Zustandsverwaltung
└── commonTest/kotlin/at/mocode/client/
├── data/service/
│ ├── PingResponseTest.kt # Datenmodell-Tests
│ └── PingServiceTest.kt # Service-Schicht-Tests
└── ui/viewmodel/
└── PingViewModelTest.kt # ViewModel- und Zustands-Tests
MVVM-Muster Implementierung
PingUiState (Sealed Class):
Initial- Neutrale Nachricht, Button aktivLoading- Ladeindikator, Button deaktiviertSuccess- Positive Antwortanzeige, Button aktivError- Klare Fehlernachricht, Button aktiv
PingViewModel:
- Verwaltet UI-Zustandsübergänge
- Behandelt Coroutine-Lebenszyklus
- Ordnungsgemäße Ressourcenentsorgung
PingService:
- HTTP-Client-Verwaltung
- Result-Wrapper-Muster
- Ressourcen-Bereinigungsunterstützung
Abhängigkeiten
Laufzeit-Abhängigkeiten
// Compose Multiplatform UI
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
// Netzwerk & Serialisierung
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.contentNegotiation)
implementation(libs.ktor.client.serialization.kotlinx.json)
implementation(libs.kotlinx.serialization.json)
// Coroutines
implementation(libs.kotlinx.coroutines.core)
Plattformspezifische Abhängigkeiten
// JVM (Desktop)
jvmMain {
implementation(libs.ktor.client.cio)
}
// JS (Web)
jsMain {
implementation(libs.ktor.client.js)
}
Test-Abhängigkeiten
commonTest {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
}
Verwendung
Grundlegende Integration
@Composable
fun YourApplication() {
// Verwendet at.mocode.client.ui.App
App(baseUrl = "https://your-api.com")
}
Erweiterte Verwendung mit benutzerdefinierter Konfiguration
// Benutzerdefinierte Service-Konfiguration
// Verwendet at.mocode.client.data.service.PingService
val customService = PingService(
baseUrl = "https://custom-api.com",
httpClient = createCustomHttpClient()
)
// Benutzerdefiniertes ViewModel mit spezifischem Scope
// Verwendet at.mocode.client.ui.viewmodel.PingViewModel
val customViewModel = PingViewModel(
pingService = customService,
coroutineScope = customCoroutineScope
)
API-Referenz
PingService
class PingService(
private val baseUrl: String = "http://localhost:8080",
private val httpClient: HttpClient = createDefaultHttpClient()
) {
suspend fun ping(): Result<PingResponse>
fun close()
companion object {
fun createDefaultHttpClient(): HttpClient
}
}
PingViewModel
class PingViewModel(
private val pingService: PingService,
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
) {
var uiState: PingUiState by mutableStateOf(PingUiState.Initial)
private set
fun pingBackend()
fun dispose()
}
PingUiState
sealed class PingUiState {
data object Initial : PingUiState()
data object Loading : PingUiState()
data class Success(val response: PingResponse) : PingUiState()
data class Error(val message: String) : PingUiState()
}
Entwicklung
Das Modul erstellen
# Für alle Plattformen kompilieren
./gradlew :client:common-ui:build
# Nur JVM-Kompilierung
./gradlew :client:common-ui:compileKotlinJvm
# Nur JavaScript-Kompilierung
./gradlew :client:common-ui:compileKotlinJs
Tests ausführen
# Alle Tests ausführen
./gradlew :client:common-ui:jvmTest
# Spezifische Testklasse ausführen
./gradlew :client:common-ui:jvmTest --tests "PingViewModelTest"
Codequalität
Das Modul hält hohe Codequalitätsstandards aufrecht:
- Testabdeckung: 32 umfassende Tests über alle Schichten
- Architektur-Konformität: 100% MVVM-Muster-Einhaltung
- Ressourcenverwaltung: Ordnungsgemäßer Lebenszyklus und Bereinigung
- Speichersicherheit: Keine Speicherlecks durch ordnungsgemäße Entsorgung
Tests
Testabdeckung Übersicht
| Komponente | Test-Datei | Tests | Abdeckung |
|---|---|---|---|
| PingResponse | PingResponseTest.kt | 7 | Datenmodell, Serialisierung |
| PingService | PingServiceTest.kt | 10 | HTTP-Service, Lebenszyklus |
| PingViewModel | PingViewModelTest.kt | 8 | MVVM, Zustandsverwaltung |
Spezifische Test-Suites ausführen
# Datenschicht-Tests
./gradlew :client:common-ui:jvmTest --tests "*PingResponseTest*"
# Service-Schicht-Tests
./gradlew :client:common-ui:jvmTest --tests "*PingServiceTest*"
# ViewModel-Tests
./gradlew :client:common-ui:jvmTest --tests "*PingViewModelTest*"
Architektur-Vorteile
🏗️ Moderne MVVM-Implementierung
- Testbarkeit: Ordnungsgemäße Dependency Injection ermöglicht umfassende Unit-Tests
- Wartbarkeit: Klare Trennung der Belange und Single-Responsibility-Prinzip
- Skalierbarkeit: Architektur unterstützt zukünftige Funktionserweiterungen nahtlos
🚀 Laufzeit-Effizienz
- Ressourcenverwaltung: Ordnungsgemäße HttpClient-Bereinigung verhindert Speicherlecks
- Leistung: Eliminierung unnötiger Operationen und Callback-Muster
- Stabilität: Verbesserte Fehlerbehandlung und Zustandsverwaltung
🔧 Entwicklererfahrung
- Code-Klarheit: Selbstdokumentierender Code mit Sealed Classes und klarer Benennung
- Debugging: Einfache Zustandsverfolgung und Problemidentifikation
- Integration: Einfaches Integrationsmuster für abhängige Module
Migrations-Hinweise
Von der vorherigen Implementierung
Das Modul wurde vollständig von einem komponentenbasierten Ansatz zu MVVM refaktoriert:
Vorher (Komponentenbasiert):
- Vermischte Belange in einzelnen Dateien
- Callback-basierte Zustandsverwaltung
- Manuelle Ressourcenverwaltung
- Speicherleck-Potenzial
Nachher (MVVM):
- Klare Trennung der Belange
- Compose-Zustandsverwaltung
- Automatische Ressourcenbereinigung
- Speicherleck-Prävention
Breaking Changes
Keine - Das Refactoring behielt vollständige Rückwärtskompatibilität für abhängige Module bei.
Zukünftige Entwicklung
Empfohlene Verbesserungen
-
Konfigurationsverwaltung
- Umgebungsspezifische Einstellungen
- Konfigurationsvalidierung
-
Fehlerbehandlung
- Spezifische Fehlertypen
- Wiederholungsmechanismen für Netzwerkausfälle
-
Monitoring-Integration
- Metriken-Sammlung
- Leistungsüberwachung
-
Internationalisierung
- Mehrsprachige Unterstützung
- Sprachspezifische Formatierung
Mitwirken
Entwicklungsumgebung einrichten
- Stellen Sie sicher, dass JDK 21 installiert ist
- Klonen Sie das Repository
- Führen Sie
./gradlew :client:common-ui:buildaus, um die Einrichtung zu verifizieren
Code-Standards
- Befolgen Sie Kotlin-Codierungskonventionen
- Fügen Sie Tests für neue Funktionalität hinzu
- Behalten Sie MVVM-Architekturmuster bei
- Stellen Sie ordnungsgemäße Ressourcenverwaltung sicher
Test-Anforderungen
- Alle öffentlichen APIs müssen Tests haben
- Mindestens 90% Testabdeckung für neue Features
- Integrationstests für modulübergreifende Funktionalität
Fehlerbehebung
Häufige Probleme
| Problem | Lösung |
|---|---|
HttpClient nicht ordnungsgemäß geschlossen |
Stellen Sie sicher, dass dispose() im ViewModel aufgerufen wird |
| Zustand wird in UI nicht aktualisiert | Überprüfen Sie die Compose-Zustandsbeobachtung-Einrichtung |
| Netzwerk-Timeouts | Überprüfen Sie baseUrl-Konfiguration und Konnektivität |
| Test-Fehler auf JS-Plattform | Verwenden Sie JS-kompatible Test-Muster (keine Reflection) |
Debug-Informationen
# Abhängigkeitskonflikte überprüfen
./gradlew :client:common-ui:dependencies
# Ausführliche Test-Ausgabe
./gradlew :client:common-ui:jvmTest --info
# Build-Scan für detaillierte Analyse
./gradlew :client:common-ui:build --scan
Modul-Status: ✅ Produktionsbereit Architektur: ✅ MVVM-konform Testabdeckung: ✅ Umfassend (32 Tests) Dokumentation: ✅ Vollständig
Zuletzt aktualisiert: 16. August 2025