<@U04JK1XE00P> <https://kotlinlang.slack.com/archi...
# android-architecture
c
This is usually a very good starting point.
f
this is not a particular design pattern, just a layering of the app into a UI, Domain and Data layers. You can implement any design pattern you want on top of this
I personally like MVI, especially for compose, because • allows me to expose the UI state as a single class, so only have to observe 1 stream • makes it easier to reason about changes to the state as they are all happening in a single place (the reducer), and also easier to test as the reducer is a pure function
e
One class for all screens or per screen?
f
per screen
e
I was just reading this critique (+

video

) by @zhuinden, which argues that MVI's centralized state is a holdover from Javascript fraught with problems. I don’t have strong feelings yet but it made sense to me. Has anyone done it both ways long enough to have an opinion?
z
Considering "MVI" immediately falls apart the moment you try to use SavedStateHandle, I'm surprised it's still "popular" even after 2020. MVI was always somewhat unnecessary because we have types, but when SavedStateHandle's api comes into play, it's effectively detrimental to correct app behavior and interaction with Jetpack APIs
f
opinions on design patterns are all over the place. The usual rule applies: evaluate available options, choose what better fits your need, don't take what you read on the net at face value without doing your own research
case in point, from the article
Copy code
When using MVI, this would require evaluating the results for every single character in order to get the latest list, even though we only care about the latest user input.

Theoretically with reactive operators, we could use either debounce (to reduce the number of requests within a given time frame) and switchMap/flatMapLatest, however using a state reducer makes this impossible. You cannot skip state evaluation!
this is not true, you can do debouncing on MVI. You can use a middleware to handle asynchronous operations while the reducer is solely responsible for synchronosly updating the state. The middleware can do debouncing and push a request to the reducer to update the state only after the debounce timeout has lapsed.
e
Isn’t that just adding another layer of complexity? To gain what? Can you point to an example that shows how to do it right?
f
I would say it's a way to manage complexity instead. You break your business logic into chunks, a set of middlewares to handle asynchronous work, and a reducer to update the state synchronously. About an example that shows how to do it right, what is right or not will vary on many variables and how you feel about this approach. I can show you how I do it, but that does not mean it's right or the best solution for your needs. This project uses MVI with middleware to handle asynchronous work.
🙏 3