Eleva tu app Android: patrones de arquitectura con Jetpack Compose

Eleva tu app Android: patrones de arquitectura con Jetpack Compose

Source: Dev.to

📱 ¿A qué llamamos los patrones de arquitecturas Android? ## 🧩 Componentes clave con Jetpack Compose ## 1. UI (Compose) ## 2. ViewModel ## 3. Domain / Business Logic ## 4. Data Layer ## 🏗️ Patrones de arquitectura más usados ## 🔹 1. MVVM (Model–View–ViewModel) ⭐⭐⭐⭐⭐ ## Estructura ## Flujo de datos (unidireccional) ## Ejemplo simple ## 🔹 2. MVI (Model–View–Intent) ⭐⭐⭐⭐ ## Conceptos clave ## Ejemplo conceptual ## 🔹 3. Clean Architecture con Compose ⭐⭐⭐⭐⭐ ## Reglas ## 🧠 Recomendación oficial de Google ## 🔁 Unidirectional Data Flow (UDF) ## 📌 ¿Cuál usar? ## ✅ Conclusión ## 🔹 Referencias Son formas recomendadas de organizar el código de una app Android para que sea: Con Kotlin + Jetpack Compose, Google promueve arquitecturas reactivas y unidireccionales. Antes de los patrones, es importante entender los roles principales: El más usado y recomendado con Compose Muy popular en apps grandes No es un patrón UI, sino una arquitectura completa Esto evita bugs y hace la UI predecible. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: @Composable fun HomeScreen(state: HomeState) { Text(text = state.title) } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: @Composable fun HomeScreen(state: HomeState) { Text(text = state.title) } CODE_BLOCK: @Composable fun HomeScreen(state: HomeState) { Text(text = state.title) } CODE_BLOCK: class HomeViewModel : ViewModel() { private val _state = MutableStateFlow(HomeState()) val state = _state.asStateFlow() } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: class HomeViewModel : ViewModel() { private val _state = MutableStateFlow(HomeState()) val state = _state.asStateFlow() } CODE_BLOCK: class HomeViewModel : ViewModel() { private val _state = MutableStateFlow(HomeState()) val state = _state.asStateFlow() } CODE_BLOCK: UI (Compose) ↓ ViewModel ↓ Repository ↓ Data Source (API / DB) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: UI (Compose) ↓ ViewModel ↓ Repository ↓ Data Source (API / DB) CODE_BLOCK: UI (Compose) ↓ ViewModel ↓ Repository ↓ Data Source (API / DB) CODE_BLOCK: User Action → ViewModel → State → UI Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: User Action → ViewModel → State → UI CODE_BLOCK: User Action → ViewModel → State → UI CODE_BLOCK: @Composable fun HomeScreen(viewModel: HomeViewModel = viewModel()) { val state by viewModel.state.collectAsState() Button(onClick = { viewModel.loadData() }) { Text("Cargar") } } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: @Composable fun HomeScreen(viewModel: HomeViewModel = viewModel()) { val state by viewModel.state.collectAsState() Button(onClick = { viewModel.loadData() }) { Text("Cargar") } } CODE_BLOCK: @Composable fun HomeScreen(viewModel: HomeViewModel = viewModel()) { val state by viewModel.state.collectAsState() Button(onClick = { viewModel.loadData() }) { Text("Cargar") } } CODE_BLOCK: Intent → ViewModel → Reducer → New State → UI Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: Intent → ViewModel → Reducer → New State → UI CODE_BLOCK: Intent → ViewModel → Reducer → New State → UI CODE_BLOCK: sealed class HomeIntent { object LoadData : HomeIntent() } data class HomeState(val loading: Boolean = false) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: sealed class HomeIntent { object LoadData : HomeIntent() } data class HomeState(val loading: Boolean = false) CODE_BLOCK: sealed class HomeIntent { object LoadData : HomeIntent() } data class HomeState(val loading: Boolean = false) CODE_BLOCK: Presentation (Compose + ViewModel) Domain (UseCases) Data (Repository, API, DB) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: Presentation (Compose + ViewModel) Domain (UseCases) Data (Repository, API, DB) CODE_BLOCK: Presentation (Compose + ViewModel) Domain (UseCases) Data (Repository, API, DB) CODE_BLOCK: Event → ViewModel → State → Compose UI Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: Event → ViewModel → State → Compose UI CODE_BLOCK: Event → ViewModel → State → Compose UI - Más mantenible - Más escalable - Más testeable - Más fácil de entender en equipo - Funciones @Composable - Solo muestran el estado - No contienen lógica de negocio - Reaccionan a cambios de estado - Maneja el estado de la UI - Contiene la lógica de presentación - Sobrevive a cambios de configuración - Expone StateFlow o LiveData - Reglas de negocio - Casos de uso (UseCases) - Independiente de Android - Repositorios - APIs (Retrofit) - Base de datos (Room) - Separación clara de responsabilidades - Fácil testing - Ideal para Compose - Intent: acción del usuario - State: estado completo de la pantalla - Reducer: transforma el estado - Estado inmutable - Flujo predecible - Ideal para UIs complejas - Más código y complejidad - Las capas internas no dependen de las externas - UI no conoce detalles de datos - Muy testeable - Ideal para proyectos grandes - MVVM + Unidirectional Data Flow + StateFlow + Jetpack Compose - ViewModel como fuente única de estado - Compose solo observa y renderiza - Estado inmutable - Eventos separados del estado - Jetpack Compose cambia la forma de pensar la UI - MVVM sigue siendo la base - El estado es el corazón de la app - Flujo unidireccional = menos errores - Jetpack Compose Documentation - Guide to app architecture - Clean Architecture in Kotlin