I am trying to build an Android app using DDD/Clean Architecture. Below are three of my understandings for context:
The Domain Layer/UseCase should contain only pure business logic. It should not use any platform-specific libraries and should be written in pure Kotlin.
Suspending functions, such as those that fetch data from a database or make network API calls, should be thread-safe so they can be called from the main thread (as libraries like Retrofit do). Therefore, if I launch a coroutine in viewModelScope from ViewModel, it is not considered good practice to switch contexts (to IO/Main Dispatcher) within the ViewModel.
Not only functions that fetch data from the database or network run in a background thread, but expensive operations such as business logic or data processing should also run on a worker thread to keep the main thread unblocked.
Now, my problem is as follows:
In my Domain Layer, I have a UseCase that involves performing expensive business logic (e.g., processing a large list of data received from the database). This business logic might not necessarily call any suspending functions, but it is still cpu-intensive.
As I understand it, I should run this logic in a worker thread (Dispatchers.Default
).
How should I achieve this?
I can simply make my UseCase a suspend function, but that alone does not ensure the UseCase is safe to run on the main thread.
Along with making my UseCase a suspend function, I can switch the context to worker threads using withContext(Dispatchers.Default)
.
These are coroutine-specific functions.
Am I allowed to use this in my Domain layer, which is supposed to be platform-independent?
If I am allowed, as I understand Kotlin Coroutines are a feature of the Kotlin language and can run outside Android,
does switching context within the UseCase adhere to Clean Architecture principles?
Yes it is allowed in Clean Architecture, coroutines are part of Kotlin features, not Android specific Kotlin feature, therefore switching contexts is allowed.