Repository Pattern4/32

Lectura

En esta clase te hablar茅 de un concepto muy importante que manejaremos en la capa de datos: el patr贸n de repositorio (Repository Pattern).

El patr贸n de repositorio es un patr贸n de tipo estructural cuyo objetivo es abstraer cada operaci贸n que se realiza sobre la capa de datos.

Ventajas

Algunas de las ventajas que te da este patr贸n estructural son:

  • Las capas superiores no conocen los detalles de la implementaci贸n de las operaciones dentro de la capa de datos.
  • Cada operaci贸n est谩 encapsulada en un solo sitio, y con ello el c贸digo se puede reusar f谩cilmente.
  • Se vuelve f谩cil de aislar y realizar pruebas unitarias para comprobar su funcionamiento.
  • Puedes reemplazar f谩cilmente la implementaci贸n que ocurre en el repositorio, ya que se manejan interfaces (esto va de la mano con el Principio de Inversi贸n de Dependencia de SOLID).

Ejemplo

En el siguiente fragmento de c贸digo, hay dos interfaces que indican dos fuentes de datos de un jugador (Player): local (LocalPlayerDataSource) y remoto (RemotePlayerDataSource). Con estas interfaces solo sabes qu茅 comportamiento esperar de una fuente local y una remota, pero la implementaci贸n depender谩 de otra capa m谩s especializada (la fuente local puede ser una base de datos o un archivo, mientras que la fuente remota puede ser una API web utilizando Retrofit o Volley).

interface LocalPlayerDataSource {
    fun saveFavoritePlayer(player: Player): Boolean
}

interface RemotePlayerDataSource {
    fun getPlayerList(playerList)
}

A continuaci贸n tendr谩s tu clase del repositorio para el jugador (PlayerRepository), el cual utilizar谩 estas dos fuentes de datos, y decidir谩 en qu茅 flujos utilizarlos (se obtiene la lista de jugadores de la fuente remota mientras que se guarda un jugador favorito usando la fuente local).

class PlayerRepository(
    private val localPlayerDataSource: LocalPlayerDataSource,
    private val remotePlayerDataSource: RemotePlayerDataSource
){
    fun getPlayerList(): List<Player> = remotePlayerDataSource.getPlayerList()
    
    fun saveFavoritePlayer(player: Player): Boolean = localPlayerDataSource.saveFavoritePlayer(player)
}

Finalmente quien utilice el repositorio (usando Clean Architecture ser谩 un caso de uso) no tiene idea del detalle de la implementaci贸n, tan solo se limitar谩 a pedir la informaci贸n que necesita.

class GetPlayerListUseCase(private val repository: PlayerRepository){
    fun invoke(): List<Player> = playerRepository.getPlayerList()
}

class SaveFavoritePlayerUseCase(private val repository: PlayerRepository){
    fun invoke(player: Player): Boolean = playerRepository.saveFavoritePlayer(player)
}

En conclusi贸n, el patr贸n de repositorio es una excelente opci贸n para manejar el flujo de datos de tu proyecto, haciendo el proceso m谩s f谩cil tanto de implementar como de reemplazar fuentes de datos.

Aportes 2

Preguntas 1

Ordenar por: