Sukurk krepšelio MVI — 4 failai (data → presentation)
Šis žingsnis sukuria keturis krepšelio failus. Jie kodo stulpelyje kaip skirtukai, tvarka data → presentation — kurk iš viršaus į apačią, nes kiekvienas priklauso nuo ankstesnio. Sukursi ViewModel pirmą — gausi keturias raudonas kompiliavimo klaidas ir jokio supratimo kodėl.
1. CartItem.kt (data) — viena krepšelio eilutė: pica plius kiekis. Nieko daugiau.
2. CartEvent.kt (presentation) — viskas, ką vartotojas gali padaryti, kaip sealed interface:
sealed interface CartEvent {
data class AddItem(val menuItem: MenuItem) : CartEvent
data class IncreaseQuantity(val menuItem: MenuItem) : CartEvent
// …po vieną atvejį kiekvienam veiksmui
}
3. CartUiState.kt (presentation) — visa būsena. Esminė mintis: suma išvestinė, ne saugoma:
val totalPrice: Double get() = items.sumOf { it.menuItem.price * it.quantity }
Ji apskaičiuojama iš items kiekvieną kartą skaitant, todėl niekada negali „prasilenkti" su tikru krepšeliu.
4. CartViewModel.kt (presentation) — logika. onEvent(...) priima kiekvieną įvykį ir per _uiState.update { it.copy(...) } pagamina naują būseną. MutableStateFlow privatus (_uiState); išorei atskleidžiam tik skaityti (uiState).
Patikrink. Projektas kompiliuojasi be klaidų. Loginį veikimą galima pasitikrinti mintyse: AddItem(Margherita) du kartus → items turi vieną CartItem su quantity = 2, totalPrice = 17.00.
Spąstai. MVI būsena — nekintama (immutable). Nepamėgink laikyti
MutableListir jo keisti vietoje:// BLOGAI — Compose NEpersipieš: _uiState.value.items.add(CartItem(item, 1)) // keiti tą patį sąrašą
StateFlowpraneša apie pokytį tik kai pasikeičia reikšmė (naujacopy). Jei keiti seną objektą vietoje, nuoroda ta pati → UI nieko nepastebi, suma neatsinaujina. Visada gamink naują būseną:_uiState.update { it.copy(items = newItems) }.