Repository Pattern in Android
Repository Pattern in Android
The Repository pattern is a design pattern that abstracts data access behind a clean API, decoupling the rest of the application from the specifics of how data is fetched, cached, and persisted. In Android, repositories sit between ViewModels and data sources (network APIs, local databases, in memory caches), providing a single entry point for data operations. By the end of this lesson, you will be able to:
- Explain the role of the Repository as a mediator between data sources and consumers.
- Describe how the pattern enables offline first data strategies with local and remote sources.
- Apply the single source of truth principle using a local database as the canonical data store.
- Design repository interfaces that expose suspend functions and Flow for reactive data streams.
- Test repositories by substituting fake data sources through dependency injection.
The Repository as Data Mediator
A Repository encapsulates the logic for deciding which data source to query, how to cache results, and how to synchronize between local and remote sources. The ViewModel calls a single method on the repository and receives data without knowing whether it came from the network, a database, or an in memory cache.
interface ArticleRepository {
fun getArticles(): Flow<List<Article>>
suspend fun refreshArticles()
}
The interface exposes two operations: a Flow that emits the current list of articles (and subsequent updates), and a suspend function to trigger a refresh from the network. The ViewModel does not know or care about Retrofit, Room, or caching logic. It depends only on this interface.
This decoupling provides three benefits. First, the ViewModel is testable without real network or database dependencies. Second, the data source implementation can change (switching from Retrofit to Ktor, or from Room to SQLDelight) without modifying any ViewModel code. Third, caching and synchronization logic is centralized in one place rather than scattered across multiple ViewModels.
Single Source of Truth
The single source of truth pattern uses the local database as the canonical data store. The network is treated as a synchronization mechanism, not a primary data source. The repository writes network responses into the database and exposes the database as a Flow to the UI layer.
class ArticleRepositoryImpl(
private val api: ArticleApi,
private val dao: ArticleDao
) : ArticleRepository {
override fun getArticles(): Flow<List<Article>> {
return dao.observeAll()
}
override suspend fun refreshArticles() {
withContext(Dispatchers.IO) {
val remote = api.fetchArticles()
dao.insertAll(remote)
}
}
}
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor