Blueprint Samples¶
These samples showcase how you may integrate Blueprint in your project by implementing a simple note taking app.
There are 2 flavors of the demo app:
- demo-coroutines - powered by Kotlin Coroutines and Flow and various Blueprint libraries.
- demo-rx - powered by RxJava 3 and various Blueprint libraries.
Dependencies¶
Since the 2 demo apps have identical functionality, we are able to share a lot of common code between the apps by having a couple of common library modules.
demo-coroutines¶
This app module uses the following Blueprint libraries:
It also depends on the demo-common and demo-testing-common modules.
demo-rx¶
This app module uses the following Blueprint libraries:
It also depends on the demo-common and demo-testing-common modules.
demo-common¶
This library module includes common code shared between the 2 apps such as resources, layouts, and in-memory cache.
demo-testing-common¶
This library module includes common UI testing infra code shared between the 2 apps such as instrumentation robots and test data.
Comparison¶
The demo apps follow Clean Architecture, but the only part relevant to Blueprint is the domain layer which contains Use Cases (also known as Interactors).
One of the key differences between the Coroutines-based and RxJava-based implementations is how Interactors are implemented:
- The Coroutines-based implementation uses
SuspendingInteractorfor single-shot tasks andFlowInteractorfor cold streams. - The RxJava-based implementation uses
SingleInteractorandCompletableInteractorfor single-shot tasks andObservableInteractorfor cold streams.
| Single-shot Task | Cold Stream | |
|---|---|---|
| blueprint-interactor-coroutines | SuspendingInteractor | FlowInteractor |
| blueprint-interactor-rx3 | SingleInteractor, CompletableInteractor | ObservableInteractor |
Consequently the 2 different Interactor implementations expose different async primitives to downstream:
- Coroutines-based Interactors - expose
suspendfunction and KotlinFlowto consumers. - RxJava-based Interactors - expose RxJava
Single,CompletableandObservableto consumers.
Another difference is the wrapper APIs for encapsulated threading behavior:
- The Coroutines-based implementation uses
CoroutineDispatcherProviderfrom theblueprint-async-coroutineslibrary. - The RxJava-based implementation uses
SchedulerProviderfrom theblueprint-async-rx3library.
They offer the same abstraction to help with DI and testing, but one interacts with Kotlin’s CoroutineDispatcher API and the other one interacts with RxJava’s Scheduler API.
Notes¶
While these samples implement layered-architecture and have comprehensive unit tests and UI tests, they most definitely do not represent how one should approach building a production quality app.
A number of important things are left out as our focus here is how the Blueprint libraries can be integrated in your codebase:
- We implemented a very simple Dependency Injection (Service Locator to be precise) framework. Consider using Dagger or Koin in a real project.
- Different layers (e.g. domain, data, presentation) should probably live in their own modules in a real project.
- Both samples use AndroidX
ViewModelin the presentation layer. For better managing complex states you might want to consider using a redux-based architecture that employs Uni-directional Data Flow. I personally recommend RxRedux and its Coroutines-based equivalent. - In a real project you will want to set up product flavors for different environments (e.g. mock, staging, production).
- Obviously the apps don’t talk to any backend APIs and lack persistent storage.
For a better representation of a highly-modularized, production-quality app that uses Blueprint, you may want to take a look at ReleaseProbe.