One Off the Slack: Deduplication and Composables
Chris asked:
How do you know where to draw the line when building components? How was it decided to build a
Box
but to not create aCircle
composable? I find myself wanting to break everything out into reusable components and rather than just creating the page I need, I end up building a whole infrastructure of components behind it.
Later in the thread, Google’s Sean McQuillan provided a direct answer on the Box
-and-Circle
concern:
Box
is in because we found the regular need for a simplest single child composable that doesn’t impose a layout when we used Compose ourselves. As well as a lot of discussion.Circle
hasn’t been discussed as a Composable itself because it’s already handled by clip and applied to any composable (e.g. aBox
). Since we already have one abstraction for non-square shapes adding a second might make the framework harder to learn.
In terms of general de-duplication, Zach Klippenstein cited the rule of three, which basically states “two copies is fine, three copies suggests refactoring”
However, there are other concerns to take into account:
-
The readabilility of the code, as Timo Drick pointed out. Having complex nested composables directly declared as parameter values to another composable may make the code difficult to read.
-
The level of parameter passing that is required, as Kiran Rao mentioned (“by not breaking down into smaller components, you can take advantage of kotlin’s lexical scoping, so you don’t have to keep passing parameters down the tree”)
Google’s Adam Powell mentioned that he is “22 pages into a draft of compose API guidelines”. That will be a fascinating document to read if it is public (versus being purely for internal Google consumption).
I also agree with Sean McQuillan’s comments on how composables likely will evolve
in larger projects. While it may be tempting to make your screens based directly
on common composables like Button
, you will need to take into account how you
plan on having a centrally-defined look-and-feel for those widgets. Projects may
wind up with a library of app-specific composables that just call through to stock composables
(like Button
) with default parameter values that impose the common style. Or, as Sean
put it:
Basically, encapsulating the contract of “this is what a Button will look like / do” and then using it instead of the framework Button I’d expect in a largeish code base (10+ devs) it’d make sense to make a custom version of most of the drawing components with a API that only supports what your app allows (Text, Button, etc). Probably less often for layouts (Row, etc)
Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!