Mental Models of Jetpack Compose #3: Inheritance, Composition, and why they matter
TL;DR: https://en.wikipedia.org/wiki/Composition_over_inheritance
Previously, on MMoJC:
- We talked about what even is mental model
- We talked about what is state
- We talked about what is Programming Model
- We talked about Declarative UI
- We talked about separation of concerns
And for today, Iâd like to talk about Inheritance & Composition in the context (no not that Contextđ) of Android.
Inheritance
Android was born (officially) in 2008: Java 1.6, JavaScript is just some things you use to animate stuff, not build a full blown web app, not even the word âappâ is a thing just yet. And when it comes time to build all the basic view components, there are probably quite a lot of restrictions on what they can build in a limited amount of time (esp. since iPhone just got released, the pressure is on!). So in order to encourage code-reuse (i.e. DRY), they made a View class that every classes extend from, and then they can add extra functionality, and it just keep growing like that, just like a tree.
Whatâs wrong with inheritance
While it definitely helps everyone to reuse UI code, like âButton donât have to implement their own text rendering logicâ, it is also very limiting on building complex things, which turns out to be the case, when Android become the most popular OS in the world.
For example: Button with an image instead of text. When I first start learning Android, at some point I was trying to use an image instead of text for a button, so when I find ImageButton, I was like âjackpotâ, and just converted it in the XML. but then 20 seconds later, everything broke, and I got a bunch of compile error. Turns out a lot of the functions that I was calling from the Java side donât work anymore, and itâs because Button and ImageButton, although share a very similar name, has almost nothing in common đ
Maybe the Android team could have design these 2 views the other way around? But in general I hope you got the point of âhow difficult it is to predict how people mutate their UI, and what would be the best hierarchy to ensure high level of compatibilityâ.
There is another way people discover this to be an issue over time, and itâs when people try to update existing UI: we get some ticket on what new feature we needs to implement in the UI, we updated that View, and make sure itâs covered with test. What could possibly go wrong? Well, if you are building a library of views that thousands if not millions of other classes inherent from, too bad! Since there is no clear mechanism to warn every single places that extends from you to double check if the change in behaviour is acceptable, you kinda just have to prey nothing went wrong. One example that the Google team pointed out is the âselectable text in Buttonâ, which maybe 3 apps in the world needs it.
TL;DR: Building UI with inheritance does not scale over space and time
(BTW inheritance is not the only thing that didnât aged well with View, but thatâs story for another day)
Composition: Is it the answer we are looking for?
So how else can we build reuseable View? For that, let see if composition helps: Instead of saying âButton = modify view to show text, and modify text to have a specific styleâ, just say âButton = Whatever hint you want + some background + click callbackâ. And an example for that can be seen in Flutter, like this:
And all of these are technically possible in the past, but the developer experience/ergonomics will be so bad, no one will like to develop for the platform to begin with! With much better tooling like IDE with crazy-good autocomplete support, build system that can process a huge amount of dependencies, and stack traces that gets more and more human-friendly over time, we are start to utilize composition to our advantage!
So is it the âultimateâ solution to UI building? Itâs closer, but there are still some gaps to fill, and with the each of the composition-based UI framework, there are different trade-offs theyâve made, and thatâs what we will cover in the next chapter!
Hope you like what I have wrote, and if you have any feedback or anything, feel free to leave a comments down below! Thanks!