Following yesterday’s post and “heated” thread discussion, which was really helpful, I am now presenting a new diagram, which hopefully clarifies the points and removes the confusion.
@jw made very meaningful observations, by pointing out that architecturally there is no difference at all between Declarative and Imperative UIs. You can apply MVI/unidirectional data flow in exactly the same way, for both.
My yesterday’s diagram was indeed confusing, by hinting a unidirectional data flow just for the Declarative UIs.
But there is an important difference between Declarative and Imperative UIs, and that is cohesion. In Declarative UIs, you just have 1 layer (Compose/SwiftUI), while in Imperative UIs, you have 2 layers (one of Kotlin/Swift code, and one of XMLLayout/InterfaceBuilder). This also means that each UI component introduces an extra relationship (coupling) between the 2 layers, which needs to be managed, with extra boilerplate code.
Android has been trying to minimize this problem by introducing the ViewBinding, but the same mechanism doesn’t exist in iOS InterfaceBuilder, where the coupling between the 2 layers needs to be kept updated manually.
Declarative UIs don’t have this low-cohesion issue, as the data can be applied directly on the UI layout, without an extra middle layer. This removes a lot of boilerplate code and clearly speeds up development.
12/08/2020, 3:12 PM
you can do the same thing on Android in the top picture by using databinding and attaching it to LiveState in ViewModels FYI
So diagram is missing that third state.
12/08/2020, 3:20 PM
@kenkyee In this new diagram I have removed any reference to the architecture and to the ViewModel <> UI relationship. You can use MVP or MVI, LiveData or StateFlow, the same applies.
With ViewBinding, the relationship between the 2 layers is simplified, but the 2 separate layers to manage still exist.
12/08/2020, 4:43 PM
Yep... Left side would be fragment.
Same would be true of compose if it's in interop mode
12/08/2020, 8:30 PM
Nice work @Daniele B 👍 I followed the thread yesterday and I must admit I winced because it came across as the typical queue of people ready to tell someone everything they'd done wrong and not what they'd done right... but sure that is helpful, taken in the right way; and there were some very insightful observations made.
Thanks for relentlessly pursuing the essence of what can make the combination of Declarative UI pattern + KMP powerful, and developing the ideas in public, I've enjoyed following your process.
Also thanks to some encouragement from you the other day I'm back on track with plans to roll this approach into a commercial PoC! 🎉 K
12/08/2020, 8:52 PM
Thanks @darkmoon_uk! I have actually learned a lot from yesterday’s discussion. It’s invaluable to have a platform like Slack to share ideas with people in the field, and get feedback.
Surely I was showing a poor representation of the point I wanted to make. Jake Wharton was clearly trying to be provocative, but he is a smart guy and he had the point.
In order to explain the real difference between Declarative and Imperative UIs, it’s definitely very useful to remove any element related to the architecture.
I was making the mistake of wrapping the Declarative UIs into an MVI pattern, which was creating confusion. By removing the architectural elements, it became even more evident what is the real difference between the Declarative and Imperative UIs. And it’s first of all about “cohesion”. With Imperative UIs you have a very low cohesion, as you need to switch between two different domains, which always brings some kind of replication. On Declarative UIs you just have one domain, and this makes things incredibly more smooth.
The merit of 85% shared code is clearly a lot about the Declarative UIs. You wouldn’t be able to achieve that much with an Imperative UI toolkit. No matter how smart you want to be, there is always going to be some extra boilerplate code. ViewBinding (on Android) helps a lot, but that’s clearly a temporary solution. You definitely want to make a full switch to Declarative UI as soon as you can, especially as they will be the only toolkits that will keep being updated in the future.