Clean Architecture extends the MVVM pattern from the Proficient course by inserting an explicit Domain layer between Presentation and Data, containing plain Kotlin Use Cases with no Android framework dependencies at all:
// Domain layer — no Android imports, no Retrofit/Room types leaking in
class GetPopularMoviesUseCase @Inject constructor(
private val repository: MovieRepository
) {
suspend operator fun invoke(): NetworkResult<List<Movie>> {
return repository.getPopularMovies()
}
}
// Presentation layer — depends only on the use case, not the repository directly
class MovieViewModel @Inject constructor(
private val getPopularMovies: GetPopularMoviesUseCase
) : ViewModel() {
fun loadMovies() {
viewModelScope.launch {
_uiState.value = getPopularMovies()
}
}
}
The operator fun invoke() lets you call the use case like a function: getPopularMovies() rather than getPopularMovies.execute() — a small but common Kotlin convention for single-purpose classes.
This extra layer pays off most clearly once business logic gets complex enough to be reused across multiple ViewModels/screens, or when you want to unit test business rules completely independent of Android.
- Image
- SKU
- Rating
- Price
- Stock
- Availability
- Add to cart
- Description
- Content
- Weight
- Dimensions
- Additional information