Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Clean Architecture with Jetpack Compose

Clean Architecture with Jetpack Compose

A talk that I gave for GDG UKI , describes how Android Architecture patterns transcribe to the Jetpack Compose paradigm.

Ac5b39a4b12e8ca2d6e25b9e7cc142ae?s=128

Divya Jain

May 12, 2021
Tweet

Transcript

  1. Clean Architecture with Jetpack Compose Divya Jain divyajain2405

  2. Android App Architecture ▫ Android Architecture Components ▫ MVVM, MVP,

    MVI etc buzz words ▫ Separation of concerns ▫ Test-ability ▫ Loose coupling Robust, Testable, Maintainable & Scalable Apps 2
  3. “ Jetpack Compose provides a declarative API that allows you

    to render app UI without imperatively mutating front end views making it easier & faster. 3
  4. @Composable fun TextSample() { Column(modifier = Modifier.padding(16.dp)) { var textValue

    by rememberSaveable { mutableStateOf("") } if (textValue.isNotEmpty()) { Text( text = "Text entered is: $textValue!", fontSize = 30.sp, modifier = Modifier.padding(bottom = 16.dp), ) } TextField( value = textValue, onValueChange = { textValue = it }, label = { Text("TextValue") } ) } }
  5. Key things to remember ▫ Composable functions can execute in

    random order or parallelly ▫ Compose does intelligent recomposition & skips as much as possible ▫ Recomposition can be canceled & restarted OR might run very frequently 5
  6. Unidirectional Data flow Design pattern where state flows down to

    UI and events flow up from UI 6 UI ViewModel State event
  7. @Composable fun TextSample(textValue: String, onTextValueChange: (String) -> Unit) { Column(modifier

    = Modifier.padding(16.dp)) { Text( text = "Hello, $textValue!", fontSize = 30.sp, modifier = Modifier.padding(bottom = 16.dp), ) TextField( value = textValue, onValueChange = { onTextValueChange(it) }, label = { Text("TextValue") } ) } }
  8. 8 View View ViewModel Model Event Event State

  9. class TextViewModel : ViewModel() { private val _textValue = MutableLiveData("")

    val textValue: LiveData<String> = _textValue fun onTextValueChanged(newValue: String) { _textValue.value = newValue } } 9 @Composable fun TextScreen(textViewModel: TextViewModel = viewModel()) { val textValue: String by textViewModel.textValue.observeAsState("") TextSample(textValue, textViewModel.onTextValueChanged(it)) }
  10. 10 Adopt-Happily

  11. 11 Adopt-Happily

  12. Kotlin stateflow 12 class TextViewModel : ViewModel() { private val

    _textValue: MutableStateFlow<String> = MutableStateFlow("") val textValue = _textValue.asStateFlow() fun onTextValueChanged(newValue: String) { _textValue.emit(newValue) } } @Composable fun TextScreen(textViewModel: TextViewModel = viewModel()) { val textValue = textViewModel.textValue.collectAsState().value TextSample(textValue, textViewModel.onTextValueChanged(it.value)) }
  13. MVP Data is communicated back to the view from the

    presenter imperatively, making it nearly impossible to integrate Compose. 13 View Presenter Model
  14. Conclusion ▫ UI in Compose is immutable. ▫ It only

    accepts state & expose events ▫ Unidirectional data flow pattern like MVVM fits well ▫ Using ViewModel as state holder ensures clean architecture & intelligent efficient recomposition. 14
  15. 15 Thanks! Any questions? You can find me at @divyajain2405

    on Twitter, or email me at divyajain2405@gmail.com