Skip to main content

Command Palette

Search for a command to run...

Chapter 7 - Coding the repository implementation class

Published
3 min readView as Markdown

Let us code the repository implementation class

class ArtRepositoryImpl(private val artDao: ArtDao):ArtRepositoryInterface {
     override fun getArt(): Flow<List<Art>> {

        //returns a stream (Flow) that emits a list of ArtEntity objects 
        //every time the ROOM DB table changes.
        val artStream = artDao.getAllArts()

        // For each emitted list (entityList),
       // convert each ArtEntity into an Art (domain model) 
       val artObjs = artStream.map { entityList -> entityList.map { it.toDomainModel() } }

        // return Flow<List<Art>>
        return artObjs
    }

    override fun insertArt(art: Art) {
        TODO("Not yet implemented")
    }

    override fun deleteArt(art: Art) {
        TODO("Not yet implemented")
    }

    override fun searchImage(userQuery: String): Flow<Resource<List<ImageResult>>> {
        TODO("Not yet implemented")
    }
}

The skeleton of the class tells us that the four functions that we discussed in chapter 5 have been implemented.

Our first use case GetArtUseCase will actually use only the getArt() function. Since we will access the DAO to fetch our list of Images we have used the artDao variable in the class constructor.

Now let us understand the getArt() function in depth:

  1. We get the Flow or stream of ArtEntity List containing multiple objects. This is saved in the variable artStream.

  2. Whenever the Room emits the list, the map operator intercepts that emission and we get the entire emitted list as entityList.

  3. The map operator again operates on the entityList object and we get each ArtEntity object. Each ArtEntity is now converted by the mapper function toDomainModel() to get the Art object.

Thus, entityList is one emission value from Room, and that emission value happens to be a List of ArtEntity.

We will recap our learning so far by the following UML sequence diagram.

Figure: Interaction between the Domain and Data layers for the GetArtUseCase

The UML sequence diagram illustrates how data flows from the local Room database up to the use case through the repository abstraction.

Step 1:
GetArtUseCase triggers a call to ArtRepositoryImpl (repository.getArt()) to fetch artwork data.

Step 2:
ArtRepositoryImpl delegates this call to the ArtDao by calling getAllArts().

Step 3:
ArtDao executes the Room query — "SELECT * FROM arts".

Step 4:
Room returns a Flow<List<ArtEntity>> that emits whenever the data in the table changes.

Step 5:
ArtDao passes this emitted flow back to the repository.

Step 6:
Inside the repository, each ArtEntity is transformed using a mapper (entity.toDomainModel()).

Step 7:
The mapper produces a clean list of domain models (List<Art>).

Step 8:
Finally, the repository returns a Flow<List<Art>> to the use case.

So far, we have focused on the data flow between Domain and Data layers. Later, when we introduce the Presentation layer (ViewModel and UI),this flow will extend further upward — the ViewModel will collect this Flow and update the UI state.

SUMMARY

Each numbered step in the sequence diagram corresponds to a specific interaction point between Clean Architecture layers, ensuring that the domain logic remains independent of the data source implementation.

More from this blog

Architecting Android: The Right way

31 posts

Exploring Clean Architecture in Android with Kotlin and Jetpack Compose — simplifying design patterns, testing, and app structure for curious developers.