Solutions short and working, must be. Break the app, they must not.
Wisdom we follow:
- 80/20 rule: From 20% code, 80% value.
- Complexity, a dark path it is. Easy to start, difficult to undo. More layers, tempting they seem... Yet in simplicity, true power lies.
- Overengineer, you must not. More... often is less. Clear and plain, solutions should stand.
- For today, you build. Tomorrow, uncertain is. By looking too far ahead, stumble today, you might.
Separation, the path of wisdom it is: Compose UI ≠ Logic of Screen. Why? Hmmm...
- Performance of Jetpack Compose: Less the UI thinks (computes), faster it changes (recomposes). Fewer recompositions when
UiState
is primitive and@Immutable
, app smoother runs. - DI (The Way of Injecting): Inject in composable functions, one cannot. Yet, in ViewModel with
@Inject constructor
, easy it is. - Code, simple it is: UI dumb, only draws. Logic pure, not knowing about UI doings.
- Compose Previews: Mock
UiState
, easy it becomes. Any screen state, preview you can. - Testability: ViewModel, easy to test it is - send
UiEvent
s, verifyUiState
. Simple. Hmmm... Compose UI, like celebrity is. MockedUiState
if you pass, Paparazzi screenshot tests pass will.
- Compose UI: Dumb, it is. Only draws
UiState
, thinks not.UiEvent
s it screams when touched. - UiState: A
data class
, often it is. Holds only primitive and@Immutable
values it should. - UiEvent: User's doings, captured they are (like button presses, text changes).
- ViewModel: To the UI,
UiState
it offers. Ears open toUiEvents
, it keeps. Logic of screen it holds, and tasks it performs. Ancient Compose runtime's force it wields.
Unidirectional Data Flow (UDF) wisdom this teaches. MVI (Model View Intent) it is called.
Reason, straightforward it is. More strength and simplicity, the Compose runtime has:
- Complex Flow chains and
combine
, no need there is. - Power of
LaunchedEffect
,remember
, and all Compose gifts, you have. - Simpler and less tangled code, this gives.
A tip for you: In Ivy Wallet, the
ComposeViewModel
base inherit, and set you are.
Follow offical Guide to app architecture by Google, we do. Not for fleeting trends or mere style, but for wisdom it holds. Simplicity, at its core.
Foundation it is, where data originates and resides. Persistence with databases, or fetch from afar through network calls, it handles. Stable and reliable, it must be, for all above to trust.
In the Data Layer, a balance like the sith, there is. Always two there are, neither more nor less. DataSource
, the bearer of raw data, using the might of Room DB, DataStore, or Network API. Then Repository
, wielding the power of data sources, for rightful CRUD and validation, it strives.
Heart of the business logic, here it beats. Knowledge of UI or DataSource
s, it has not. Only power of Repository
it wields. Pure and free from Android and persistence concerns, it remains. Transforms data into meaningful actions, and sets the rules the app lives by.
Face of the app, this is. Interactions with users, here they unfold. Displays data and listens to the user, it does. Lean it is, relying on lower layers for knowledge and truth. Its beauty, not in its brain, but in its looks and responsiveness.
Here, screens find their destiny. Always in twos they emerge, no more, no less - Compose UI and ComposeViewModel
, their names be. MVI I have heard.
Split our app into many modules, we do. Tangled webs (spaghetti code, coupling) we avoid, swift builds we seek. Furthermore, permits many hands to craft yet, in peace they work, not clashing (merge conflicts).
Each screen, like its own planet it is. Expanding it might, with tales of code and tales. But in its own orbit, it stays. The galaxy of code, peaceful and unshaken it remains.
Simple, our modularization path is:
- Shared
:ivy-*
modules, a few we possess. - With these modules, shared wisdom in your screens you harness.
- Each screen/feature, its own realm it claims, like
:screen-home
or:feature-something
.
To birth a new module... Invoke this chant in your terminal, you must:
./scripts/create_module.sh screen-something
Crafting a screen, you are? Inscribe its essence, you must, in
Screens.kt
(:ivy-navigation). Weave its spirit, you shall, inIvyNavGraph.kt
(:app).
"The Grug Brained Developer", seek this scroll, you must. Tales of old engineering and fun, within it rests.
Legacy code, surround us it does. To restore balance to the code force, visit "devexp" issues you must.
Seek knowledge in the "Development" realm of our Telegram sanctuary, you must. There, answers await.