-
Notifications
You must be signed in to change notification settings - Fork 0
Concept
The primary objective of the framework is to ensure scalability of the project, providing high reusability of code hierarchies by decoupling them from each other. This can be especially beneficial for a large projects to support parallel development by different teams. For small projects or MVP’s, the framework provides tools, facilitating rapid development by enabling the to be scale-ready right from the start.
This is achieved by breaking the application logic up into separate independent parts called black-boxes. Each black-box has a simple and strictly defined interface that hides the implementation from external context. Each black-box can be seen as a sub-application that may be used separately from the context of the app.
The hierarchy of black boxes forms a tree-like structure of the entire application, where each black box performs a specific task influencing the application's state at a specific moment in time.
To maintain reusability the following rule must be followed: the parent black box is aware its children black-boxes, whereas child black-boxes know nothing about the parent and the outer context. Hierarchy example:
Any UI element can be represented as a black-box: views, screens, or a collection of screens organised into a navigation flow. These elements are defined declaratively as @Composable functions with the following interface:
💡 Blackbox : F(config, dependencies, io) → Composable
Such functions grouped by a specific domain forms a Feature, which also follows the Blackbox principles. Every feature is a black-box that can be described as the aforementioned @Composable function. But in more complex scenarios, it may be represented as a factory class or a set of factory methods, producing different @Composable based on the Feature API.
In addition to visual elements, every black-box function may have business Logic and State that is mapped to these elements. Since black-box @Composable can be called multiple times during function recomposition, it is essential to have a mechanism for keeping business logic and state from being recreated at every recomposition.
To address this, each function has its own Scope tied to its lifecycle. The Scope is created during function init and lives as longer as function is active surviving system configuration changes (mostly applicable for Android). Scope decouples the Logic from the user interface and serves as the appropriate place to define DI graph of a particular function.
When the black-box is no longer active (in more technical, @Composable leaves the composition), Scope gets automatically cleared along with all the objects defined in it, resulting in proper memory management.
- View. An abstract user interface component, that may represent a screen or a part of it.
- Scope. Lifecycle aware container that is used for creating, keeping and disposing black-box function DI graph.
- Config. A set of parameters or arguments that are used to configure the black-box during initialisation.
- Dependencies. A set of external dependencies that are used by black-box function to operate.
- IO. Reactive Input/Output used for exchanging events between black-boxes.
- NavigationFlow: A component used to describe declarative navigation between black boxes.
- Coordinator. A component that encapsulates navigation logic by taking navigation details out of black-box functions, making them context-independent.