SlideShare a Scribd company logo
@fabioCollini
Fabio Collini
Architectures in the
Compose World
Architecture
State
UI
state event
https://developer.android.com/jetpack/compose/architecture
https://developer.android.com/jetpack/compose/architecture
State
UI
state event
State
UI
state event
State
Composable
state event
ViewModel
Composable
state event
ViewModel
Composable
UseCase
state event
ViewModel
Composable
UseCase
Repository
state event
ViewModel
Composable
UseCase
Repository
state event
source of truth
ViewModel
Composable
UseCase
Repository
state event
state event
source of truth
ViewModel
Composable
UseCase
Repository
state event
state event
state event
source of truth
MVVM / MVI
MVVM
/
MVI
Both MVVM and MVI are
unidirectional data
fl
ow
architectures
MVVM
The ViewModel accepts
events and exposes the
state
MVI
The state is a single
immutable object
MVI
The state is a single
immutable object


The events are managed
using a
fl
ow
UI = f(state)
UI = f(state)
always
UI = f(state)
always


most of the times
https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
https://proandroiddev.com/android-singleliveevent-redux-with-kotlin-
fl
ow-b755c70bb055
SingleLiveEvent


SharedFlow


Channel


State + LaunchedEffect
SingleLiveEvent


SharedFlow


Channel


State + LaunchedEffect


Lots of edge cases :(


Not an of
fi
cial solution yet
State
MVI
The state is a single
immutable object
data class State(

val notes: List<Note>,

/
/
.
.
.


)
data class State(

val notes: List<Note>,

/
/
.
.
.


)

data class Note(

val id: Int,

val title: String,

val checked: Boolean

)
@Composable

fun Notes(state: State, onCheckedChange: (Note)
-
>
Unit) {

/
/
.
.
.


}
Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
data class Note(

val id: Int,

val title: String,

val checked: Boolean

)
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)_
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)_

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


state = state.copy(

notes = state.notes

.map { note
-
>


if (note.id
=
=
noteToToggle.id) {

note.copy(checked = !note.checked)

} else {

note

}

}

)

}

)
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
Not
so
easy…
https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable
https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable
data class Note(

val id: Int,

val title: String,

var checked: Boolean

)

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
data class Note(

val id: Int,

val title: String,

) {

var checked: Boolean by mutableStateOf(false)

}

Notes(

state = state,

onCheckedChange = { noteToToggle
-
>


noteToToggle.checked = !noteToToggle.checked

}

)
Composable
Xml
fi
les Composables
Xml
fi
les


Custom Views
Composables
Xml
fi
les


Custom Views


Fragments
Composables
Xml
fi
les


Custom Views


Fragments


Activities
Composables
Xml
fi
les Composables
Xml
fi
les
Composables


with


state hoisting
Custom Views Composables
Custom Views
Composables


with


remember /


rememberSavable
Fragments


Activities
Composables
Fragments


Activities
Screens


with


ViewModel
Fragments


Activities
Screens


with


ViewModel
Composables


with


remember /


rememberSavable
Custom Views
Composables


with


state hoisting
Xml
fi
les
Screen
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

setContent {

MyScreen()

}

}

}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

setContent {

MyScreen()

}
_
_


}_

}

@Composable

fun MyScreen() {

/
/
.
.
.


}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}
_
_


}_

}

@Composable

fun MyScreen() {

/
/
.
.
.


}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}

}

}

@Composable

fun MyScreen() {

/
/
.
.
.


val scope = rememberCoroutineScope()

}
class MyFragment : Fragment() {

override fun onCreateView(
.
.
.
) = 

ComposeView(requireContext()).apply {

viewLifecycleOwner.lifecycleScope.launch {

/
/
.
.
.


}

setContent {

MyScreen()

}

}

}

@Composable

fun MyScreen() {

/
/
.
.
.


val scope = rememberCoroutineScope()

LaunchedEffect("
.
.
.
") {

/
/
.
.
.


}

}
https://developer.android.com/jetpack/compose/lifecycle
https://developer.android.com/jetpack/compose/lifecycle
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@AndroidEntryPoint

class MyFragment : Fragment() {

@Inject

lateinit var myInstance: MyClass

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@Composable

inline fun <reified T : Any> rememberSingletonEntryPoint(): T {

val context = LocalContext.current

return remember {

EntryPointAccessors.fromApplication(context, T
:
:
class.java)

}

}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@Singleton

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(SingletonComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberSingletonEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ActivityScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ActivityComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberActivityEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ActivityComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberActivityEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
@ComposableScoped
@Scope

annotation class ComposableScoped
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_

@DefineComponent.Builder

interface ComposableComponentBuilder {

fun build(): ComposableComponent

}
@Scope

annotation class ComposableScoped

@ComposableScoped

@DefineComponent(parent = ActivityComponent
:
:
class)

interface ComposableComponent_

@DefineComponent.Builder

interface ComposableComponentBuilder {

fun build(): ComposableComponent

}

@EntryPoint

@InstallIn(ActivityComponent
:
:
class)

interface ComposableComponentBuilderEntryPoint {

val componentBuilder: ComposableComponentBuilder

}_
@Composable

inline fun <reified T : Any> rememberComposableEntryPoint(): T {

val context = LocalContext.current

return remember {

val entryPoint = EntryPointAccessors.fromActivity(

context.getActivity(), ComposableComponentBuilderEntryPoint
:
:
class.java

)

EntryPoints.get(entryPoint.componentBuilder.build(), T
:
:
class.java)

}

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ComposableComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}
@ComposableScoped

class MyClass @Inject constructor() {

/
/
.
.
.


}

@InstallIn(ComposableComponent
:
:
class)

@EntryPoint

interface MyEntryPoint {

val myInstance: MyClass

}

@Composable

fun MyScreen() {

val entryPoint = rememberComposableEntryPoint<MyEntryPoint>()

val myInstance = entryPoint.myInstance

}
ViewModel
Are ViewModels


necessary


(or useful)


using Compose?
https://www.youtube.com/watch?v=rmv2ug-wW4U
val navController = rememberNavController()

NavHost(navController = navController) {

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen()

}

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen()

}

composable(

route = "detail/{id}",

arguments = listOf(navArgument("id") { type = IntType })

) {

DetailScreen()

}

}_
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {

composable("home") {

HomeScreen(onClick = { navController.navigate("detail/123") })

}

composable(

route = "detail/{id}",

arguments = listOf(navArgument("id") { type = IntType })

) {

DetailScreen()

}

}_
class DetailViewModel constructor(

) : ViewModel() {

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

) : ViewModel() {

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

init {

val id = savedStateHandle.get<Int>("id")

}

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

init {

val id = savedStateHandle.get<Int>("id")

viewModelScope.launch {

myUseCase.suspendMethod(id)

}

}

}_
@HiltViewModel

class DetailViewModel @Inject constructor(

private val myUseCase: MyUseCase,

savedStateHandle: SavedStateHandle

) : ViewModel() {

var state by mutableStateOf("")

private set

init {

val id = savedStateHandle.get<Int>("id")

viewModelScope.launch {

state = myUseCase.suspendMethod(id)

}

}

}_
@Composable

fun DetailScreen() {

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

val saveable = rememberSaveable {

"saved in a bundle"

}

}_
@Composable

fun DetailScreen() {

val viewModel = hiltViewModel<DetailViewModel>()

val stateConnectedToViewModelLifecycle = viewModel.state

val remembered = remember {

"executed again on configuration change and when navigating back"

}

val saveable = rememberSaveable {

"saved in a bundle"

}

LaunchedEffect(Unit) {

/
/
executed again on configuration change and when navigating back

}

}_
https://proandroiddev.com/viewmodels-using-compose-mutablestate
fl
ows-or-mutablestates-64d34ba548c5
Wrapping
up
Wrapping
up
unidirectional data
fl
ow
Wrapping
up
unidirectional data
fl
ow


screens instead of fragments
Wrapping
up
unidirectional data
fl
ow


screens instead of fragments


viewModels are still useful
Links
&
contacts
Architecting your Compose UI


developer.android.com/jetpack/compose/architecture


Jose Alcérreca - LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)


medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150


Michael Ferguson - Android SingleLiveEvent Redux with Kotlin Flow


proandroiddev.com/android-singleliveevent-redux-with-kotlin-flow-b755c70bb055


Lifecycle of composables


developer.android.com/jetpack/compose/lifecycle


Manuel Vivo - A Compose state of mind: Using Jetpack Compose's automatic state observation


www.youtube.com/watch?v=rmv2ug-wW4U


Fabio Collini - ViewModels using Compose: MutableStateFlows or MutableStates?


proandroiddev.com/viewmodels-using-compose-mutablestateflows-or-mutablestates-64d34ba548c5
@fabioCollini


linkedin.com/in/fabiocollini


github.com/fabioCollini


medium.com/@fabioCollini
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
@fabioCollini

More Related Content

What's hot

Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
Fabio Collini
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POP
Natasha Murashev
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
Natasha Murashev
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Natasha Murashev
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
Doeun KOCH
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated Types
Natasha Murashev
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
Jeado Ko
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - Components
Visual Engineering
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
Christoffer Noring
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
Macoscope
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
Bartosz Kosarzycki
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
Natasha Murashev
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
Natasha Murashev
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
Christoffer Noring
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScript
Codemotion
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
Ignacio Martín
 

What's hot (19)

Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
droidparts
droidpartsdroidparts
droidparts
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POP
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated Types
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - Components
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScript
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
 

Similar to Architectures in the compose world

Flutter
FlutterFlutter
Flutter
Dave Chao
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Mahmoud Hamed Mahmoud
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
Nataliya Patsovska
 
Unit testing UIView
Unit testing UIViewUnit testing UIView
Unit testing UIView
Pierre Felgines
 
iOS Talks 6: Unit Testing
iOS Talks 6: Unit TestingiOS Talks 6: Unit Testing
iOS Talks 6: Unit Testing
Marin Benčević
 
Property wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyProperty wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyWannitaTolaema
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
NAVER Engineering
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and Swift
Commit University
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818
Shahzain Saeed
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
PROIDEA
 
Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Azhar Satti
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
Elmar Kretzer
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_twTse-Ching Ho
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
ssuserb6c2641
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
Ivan Dolgushin
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
Oleksandr Stepanov
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
jonmarimba
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Andrzej Jóźwiak
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Co
e-Legion
 

Similar to Architectures in the compose world (20)

Flutter
FlutterFlutter
Flutter
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Unit testing UIView
Unit testing UIViewUnit testing UIView
Unit testing UIView
 
iOS Talks 6: Unit Testing
iOS Talks 6: Unit TestingiOS Talks 6: Unit Testing
iOS Talks 6: Unit Testing
 
Property wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copyProperty wrapper and how to use them with mvvm in swift ui i copy
Property wrapper and how to use them with mvvm in swift ui i copy
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and Swift
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
 
Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256Qtp Training Deepti 3 Of 44256
Qtp Training Deepti 3 Of 44256
 
Qtp Training
Qtp Training Qtp Training
Qtp Training
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Co
 

More from Fabio Collini

Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
Fabio Collini
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
Fabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
Fabio Collini
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
Fabio Collini
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Fabio Collini
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
Fabio Collini
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
Fabio Collini
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
Fabio Collini
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
Fabio Collini
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
Fabio Collini
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
Fabio Collini
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015
Fabio Collini
 
Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014
Fabio Collini
 
Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012 Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012
Fabio Collini
 
Android Widget @ whymca 2011
Android Widget @ whymca 2011Android Widget @ whymca 2011
Android Widget @ whymca 2011
Fabio Collini
 

More from Fabio Collini (17)

Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015
 
Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014Clean android code - Droidcon Italiy 2014
Clean android code - Droidcon Italiy 2014
 
Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012 Librerie su Android: come non reinventare la ruota @ whymca 2012
Librerie su Android: come non reinventare la ruota @ whymca 2012
 
Android Widget @ whymca 2011
Android Widget @ whymca 2011Android Widget @ whymca 2011
Android Widget @ whymca 2011
 

Recently uploaded

Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
kalichargn70th171
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 

Recently uploaded (20)

Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 

Architectures in the compose world