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
SuspendingInteractor
for single-shot tasks andFlowInteractor
for cold streams. - The RxJava-based implementation uses
SingleInteractor
andCompletableInteractor
for single-shot tasks andObservableInteractor
for 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
suspend
function and KotlinFlow
to consumers. - RxJava-based Interactors - expose RxJava
Single
,Completable
andObservable
to consumers.
Another difference is the wrapper APIs for encapsulated threading behavior:
- The Coroutines-based implementation uses
CoroutineDispatcherProvider
from theblueprint-async-coroutines
library. - The RxJava-based implementation uses
SchedulerProvider
from theblueprint-async-rx3
library.
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
ViewModel
in 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.