Multi module Architecture — Road Blocks
Android Studio by default creates a one module app when we create android app, as we have discussed on Clean Architecture layers with modules can be lead into some of confusion on how do we handle Database and Dependency injection.
Adavantages of Multi module
- cross-feature dependencies
- Android dynamic delivery Instant Apps
- Ownership per Team / Squads
- Shared modules
Good start to achieve the following, to start building some share modules which will act as catalyst / accelerators for app development.
Building CORE Module
Core module can be accelerators for you app to configure Network / Persistence and other commonly used features
- Provide global dependencies to your dependency injection framework like Retrofit, SharedPreferences, Room etc.
- Contain utility classes and extension functions i.e Binding Adapters
- provides for Firebase Analytics, Crashlytics, LeakCanary, Stetho, etc in the application class using providers via Dependency injection. e.g CoreModule
Refer github project : MovieDB
how do handle different state in UI like Loading / Success / Error when we invoke the data repository
“ a generic class that holds a value with its loading status Result is usually created by the Repository classes where they return `LiveData<Result<T>>` to pass back the latest data to the UI with its fetch status.”
for our app single source of truth is database, then we can build a class serves the data from database if exits or retrieves from network and updates it.
A The database serves as the single source of truth.
Therefore UI can receive data updates from database only.
* Function notify UI about:
* [Result.Status.SUCCESS] — with data from database
* [Result.Status.ERROR] — if error has occurred from any source
* [Result.Status.LOADING]
a data source base class which will WRAP the response from api with Result with different states like success / error
if there dependency used only for feature-x
module but not in feature-y
, but both of the feature include core
for basic network and persistence and other dependencies.
in this scenario , best approach will be adding all dependency in the core with api
as proguard will take care of not including it into the feature-y
dynamic feature.
How do we handle Room / Database?
When we have requirement to use databases for each feature how do we do we go database a single DB ? we could use core
module ,because we designed core
module to share common functionality our application. but we can not use because Room to work, we need a database file with all the entity classes mentioned into it and core
module does not have access to Entity classes of other feature.
solution is we will have to create a new db file into each feature
module and have a database per module.
This has some advantages:
- Migrations are modularized
- Instant apps contain only those tables they need
- Queries will be faster
Cons:
- Cross module data relations won’t be possible
working with Dagger 2?
As we hit confusion on Room same applicable for Dagger too.
core
module would not be able to access and initialise my feature
module. This is the perfect use-case for dependent modules.
Your core module mentions the dependencies it wants to expose to the dependent dependency.
dependencies define the CoreModule
can be passed as dependency to feature module.
Details and discover modules includes core module, which provides dependencies for network.
Wrap UP.
Converting monolithic application into modules is long journey , some of confusions and solution for those i tries to capture here.
Always open for comment and improvement.
share a clap if it helped you.