The Domain layer

The Domain layer

What is the domain layer?

The domain layer is responsable for encapsulating complex business logic or simple business logic that needs to be reused by multiple ViewModels.

For the Android apps it makes sense to keep Use Cases optional. Google describes this concern in their guide. Also worth to check this article

What the domain layer doesn't do

The domain layer isn't responsable for how the data is displayed, nor is responsable for storing and retrieving data. It just holds business logic

In smaller apps most of held in viewModels but as the app grows makes sense to store it on

Is made of interactions or useCases, which are single actions or tasks that the app can do


When to use a Domain Layer?

If you have simple CRUD operations it is perfectly fine to access Repository from the ViewModel without the Use Case middleware.

Implement only Use Cases which actually introduce some application logic on top of data. They can aggregate data from different sources, transform them or execute some complex processes. Don't create use cases which just forward the call to the Repository.

Benefits

Components of the Domain layer

Model

Defines the values that a data model has

Repository

Handles multiple data sources (multiple) and determine which one to use in different moments. i.e API and local database

Use case

What in MVVM you do in the viewModel now is a use case, allowing you to re-use methods
Contains the Business Logic

This gets inserted in the viewModel as a dependency

Uses repository (from whichever source is coming) and handles the business logic inside it

Implementation

Naming

You should make obvious when you're calling a domain layer action, this will greatly improve readability in your dataLayer, for that you can use the following conventions:

verb in present tense + noun/what (optional) + UseCase.

Dependencies

They can be dependen from Data layer or other useCases, but never UI Layer

Use cases and characteristics

They can be instantiated anywhere

By not having a life-cycle, they are attached to the caller's scope, so they can be instantiated every time we need to call them.

Can be used for common tasks

They can encapsulate simple and common business data, like formatting. So they can be usually located in Utility classes, or static methods.
But they often are hard to find and tend to have miscellaneous functions without purpose.
By moving it to a useCase justifies their existence and usage.

Combine data from Repositories

This can be often used in ViewModels making them larger and complex and makes harder to Test and reuse, so by moving them into their own useCases allows them to simplify that logic.

Allow access to Data Layer?

When adding useCases to your domain layer still having the UI Layer accessing directly some repositories form the Data Layer you may ask yourself; "Should I migrate all of the business data to a use case?"
And the answer to that question may depend on your project and how strict you want your architecture to be, the main benefit of doing so is that It makes testing ViewModel easier

While the main drawback is that it forces useCases everywhere.

Personal recommendation

Add usecases only when needed allowing the UI layer to access the Data Layer as required.

Relates to

References