https://kotlinlang.org logo
#compose
Title
# compose
d

Daniele B

12/05/2020, 1:56 PM
Trying to summarize the difference between the apps of the “past” and the apps of the “future”:
👍🏻 2
j

Joost Klitsie

12/05/2020, 2:34 PM
I have some questions: How is a ui layer fully decoupled from a viewmodel? Also what does declarative/imperative ui has to do with coupling? And in what way do you mean web services are ui agnostic in the future?
Also 85% sounds a bit high for shared code
d

Daniele B

12/05/2020, 2:44 PM
@Joost Klitsie Leland Richardson explains it well here, about how declarative UIs are able to have a minimum coupling with the ViewModel: https://medium.com/androiddevelopers/understanding-jetpack-compose-part-1-of-2-ca316fe39050
This picture represents it very well:
Without having to couple the data to the UI component IDs, and having a ViewModel which is fully shared, 85% is fully achievable.
This picture helps to understand too:
When I say webservices can be “UI-agnostic”, I mean that the shared client-side logic can play a big role, so that all processing can be done there. The webservices don’t need to have any knowledge about how the data is going to be used, and can provide optimized/normalized data, without any formatting/redundancy, which in previous thin-client apps were a common practice, aimed to reduced client-side logic. The shared client-side logic will do all.
j

Joost Klitsie

12/05/2020, 2:58 PM
Well that article doesnt say it is fully decoupled, it says it has less dependencies. It even states that you will always have some ui code in your application (aka coupling). I mean your viewmodel does need to provide some data your ui can display, so you will have coupling there. I do like my viewmodels to dictate the values of a view, because of testability and that means higher coupling than if you'd put mapping of domain objects to ui elements all in your view, which sacrifices testability but gives you a higher grade of decoupling.
1
I use mvvm in my test application, and i achive 9000 loc in common, 6000 in react and 3500 in my android app. So that is at best 70% on the android app, but still crazy good. I think the fancier your ui, the lower it will get. 1 project is not a good representation, i can write a lib with 1000 lines of code and then a ui with 10 lines of code, hurray 99% reused!
I think jetbrains should do a bigger survey to show the real numbers
Also your api data driven comparison doesnt really need kmp to work, this is already possible and already done nowadays id say, anyway your services will be most likely even more event driven if you look at cloud functions which are gaining popularity
d

Daniele B

12/05/2020, 3:15 PM
The “secret sauce” for achieving 85% shared code is definitely the MVI pattern and Kotlin’s StateFlow, which allows you to have a multi-platform observable (inbuilt in the language) instead of platform-specific observables such as LiveData. If you use StateFlow to pass the data to your UI layer, there is no coupling. Which means the ViewModel (which is platform-independent) doesn’t need to know anything about the platform-specific implementation of the UI. The ViewModel just provides the data. And it’s up to the UI layer to decide how to use it.
What I am saying about data-optimized webservices, is that it’s now better achievable thanks to multi-platform. Previously, when you had to replicate any logic for each platform, you tended to have webservices directly linked to screen (one API per screen), in orer to minimize client-side logic replication. Nowadays, as you can just write client-logic once, you can apply all kind of data optimizations.
j

Joost Klitsie

12/05/2020, 3:19 PM
Well i use mvvm with flows so that shouldnt have more code (as my viewmodels are in common)
I do not think passing domain objects to a view is the best thing to do
Its a shortcut
But talking about apis, we use on my project (like at my work, not kmp) we also download data objects, nothing in the api is architected to serve specific screens
d

Daniele B

12/05/2020, 3:23 PM
I do not think passing domain objects to a view is the best thing to do
it’s just data, strings, already formatted, and ready to be displayed on the UI layer. The formatting is done in the shared ViewModel.
But talking about apis, we use on my project (like at my work, not kmp) we also download data objects, nothing in the api is architected to serve specific screens
Of course, in many cases it’s important to apply client-side logic, even if the client-logic is not shared and needs to be replicated for each platform. But that comes with a cost (of replication). In KMP, there are not costs of replication, so such client-side logic can be very extensive. And many advanced things can be done to improve the user experience. At no cost.
j

Joost Klitsie

12/05/2020, 3:28 PM
Well that means some coupling right? The viewmodel has to poop out the data such that the view can display it. I mean it does have less coupling if you dont have to worry about the imperative view, but still its something
Which is fine
d

Daniele B

12/05/2020, 3:32 PM
Well that means some coupling right? The viewmodel has to poop out the data such that the view can display it. I mean it does have less coupling if you dont have to worry about the imperative view, but still its something
UI Components in the imperative (view-based) UI systems have IDs. When I talk about coupling, I mean that the ViewModel (which is not the same as saying the Android's ViewModel component) needs to link data to each UIcomponent ID. This happens in both Android and iOS, view-based system. In a KMP/MVI/DeclarativeUIs project, the ViewModel can be totally decoupled in the sense that it doesn't need to link data to UI components. It just provides the app state (which is a data object), and it's up to the declarative UI layer to use it in the way it wants.
j

Joost Klitsie

12/05/2020, 8:02 PM
I do agree with thelis point a lot: when we dont need to duplicate logic, we can invest more in extending functionality. Hybrid apps fail to be cheaper i guess because of the costs of fighting against the frameworks, kotlin doesnt have this issue. I will have a presentation soonish about kmp at my company and i do hope to convince some souls, but at the same time I'll try not to overpromise. Code sharing between backend and frontend will be a big point as well (even though its quite minimal compared to the frontend apps code sharing). Promising a new wave of apps might scare off old fashioned java guys, but promising them way better tooling might just get their attention.