Domain Layer: Use Cases & Models
Relevant source files
The following files were used as context for generating this wiki page:- domain/src/main/java/com/vocabri/domain/model/word/Word.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/AddWordUseCase.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/ObserveWordsUseCase.kt
- domain/src/main/java/com/vocabri/domain/repository/WordRepository.kt
- domain/src/main/java/com/vocabri/domain/di/DomainModule.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/DeleteWordUseCase.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/GetWordsUseCase.kt
- domain/src/main/java/com/vocabri/domain/model/word/Example.kt
- domain/src/main/java/com/vocabri/domain/model/word/WordGender.kt
- domain/src/main/java/com/vocabri/domain/usecase/word/GetWordGroupsUseCase.kt
The domain module is the core of the Vocabri application, encapsulating its business logic and rules. It is designed to be independent of other layers like UI (app) and data persistence (data), following clean architecture principles. This layer defines the essential data structures (models) that represent the application's entities, the contracts for data access (repositories), and the specific business operations (use cases) that can be performed.
This separation ensures that the core logic is testable in isolation and can be reused across different platforms, such as the planned iOS app. The primary components are the Word model, the WordRepository interface, and a set of use cases for creating, reading, and deleting words.
Core Data Models
The domain models define the structure of the data that the application works with. The central model is the Word, which is implemented as a sealed interface to represent different parts of speech with specific attributes.
Word Model Hierarchy
The Word sealed interface has several concrete implementations, each corresponding to a specific part of speech. All Word types share a common set of properties, while subclasses add properties relevant to their type.
The diagram below illustrates the class hierarchy for the Word model.
Model Properties
The following table details the properties of the Word model and its subtypes.
| Class | Property | Type | Description |
|---|---|---|---|
| Word (common) | id | String | Unique identifier for the word. |
text | String | The word itself. | |
translations | List<Translation> | A list of translations for the word. | |
examples | List<Example> | A list of usage examples. | |
| Noun | gender | WordGender? | The grammatical gender of the noun (e.g., MASCULINE, FEMININE, NEUTER). |
pluralForm | String? | The plural form of the noun. | |
| Verb | conjugation | String? | Information about the verb's conjugation. |
management | String? | Information about the verb's grammatical management (e.g., prepositions). | |
| Adjective | comparative | String? | The comparative form of the adjective. |
superlative | String? | The superlative form of the adjective. | |
| Adverb | comparative | String? | The comparative form of the adverb. |
superlative | String? | The superlative form of the adverb. |
Sources: domain/src/main/java/com/vocabri/domain/model/word/Word.kt
Repository Interface
The WordRepository interface defines the contract for data operations related to words. It abstracts the data source, allowing the domain layer to remain independent of how or where the data is stored (e.g., local database, remote API). Use cases interact with this interface, not with concrete implementations.
Sources: domain/src/main/java/com/vocabri/domain/repository/WordRepository.kt
// Source: domain/src/main/java/com/vocabri/domain/repository/WordRepository.kt
interface WordRepository {
suspend fun insertWord(word: Word)
suspend fun getWordsByPartOfSpeech(partOfSpeech: PartOfSpeech): List<Word>
fun observeWordsByPartOfSpeech(partOfSpeech: PartOfSpeech): Flow<List<Word>>
suspend fun deleteWordById(wordId: String)
}
Repository Methods
| Method | Description |
|---|---|
insertWord(word: Word) | Inserts a new word into the repository. |
getWordsByPartOfSpeech(partOfSpeech: PartOfSpeech) | Fetches a list of words, optionally filtered by part of speech. PartOfSpeech.ALL retrieves all words. |
observeWordsByPartOfSpeech(partOfSpeech: PartOfSpeech) | Returns a Flow that emits a list of words whenever the data changes. |
deleteWordById(wordId: String) | Deletes a word from the repository using its unique ID. |
Sources: domain/src/main/java/com/vocabri/domain/repository/WordRepository.kt:25-28
Use Cases
Use cases represent single, discrete business operations. They orchestrate the flow of data by using one or more repository methods to achieve a specific goal. Each use case class typically has a single public execute method.
The diagram below shows how use cases interact with the WordRepository to access Word models.
Sources: domain/src/main/java/com/vocabri/domain/usecase/word/AddWordUseCase.kt, domain/src/main/java/com/vocabri/domain/usecase/word/ObserveWordsUseCase.kt, domain/src/main/java/com/vocabri/domain/usecase/word/DeleteWordUseCase.kt, domain/src/main/java/com/vocabri/domain/repository/WordRepository.kt
Use Case Summary
| Use Case | Responsibility |
|---|---|
AddWordUseCase | Adds a new Word to the repository. |
GetWordsUseCase | Fetches a list of words for a given part of speech. |
ObserveWordsUseCase | Provides a reactive Flow of words that updates automatically. |
DeleteWordUseCase | Deletes a word by its ID. |
GetWordGroupsUseCase | Fetches all words and groups them by part of speech, returning counts. |
ObserveWordGroupsUseCase | Provides a reactive Flow of word groups that updates automatically. |
GenerateRandomWordUseCase | (Debug) Generates a random word for testing purposes. |
Sources: domain/src/main/java/com/vocabri/domain/di/DomainModule.kt:32-38
AddWordUseCase Flow
This use case is responsible for persisting a new word. It takes a Word object, calls the repository's insertWord method, and handles logging.
The sequence diagram below shows the interaction when a ViewModel uses AddWordUseCase.
ObserveWordGroupsUseCase Flow
This use case provides a reactive stream of word groupings. It observes all words from the repository, groups them by part of speech, and maps them to WordGroups objects containing counts for each group.
Dependency Injection
The domain module uses Koin for dependency injection to provide instances of the use cases to the app module. The domainModule defines factories for each use case, ensuring that a new instance is created every time one is requested. This decouples the app layer from the construction details of the use cases.
// Source: domain/src/main/java/com/vocabri/domain/di/DomainModule.kt
@ExcludeFromCoverage
val domainModule = module {
// Use Cases
factoryOf(::AddWordUseCase)
factoryOf(::GetWordsUseCase)
factoryOf(::ObserveWordsUseCase)
factoryOf(::GetWordGroupsUseCase)
factoryOf(::ObserveWordGroupsUseCase)
factoryOf(::DeleteWordUseCase)
factoryOf(::GenerateRandomWordUseCase)
}
Sources: domain/src/main/java/com/vocabri/domain/di/DomainModule.kt:29-39