Introducci贸n

1

Qu茅 aprender谩s sobre Clean Architecture en Android

2

驴Qu茅 es clean architecture?

Repaso de Conceptos Generales

3

Principios SOLID

4

Repository Pattern

Presentaci贸n del proyecto

5

Presentaci贸n del proyecto: Rick and Morty

6

Uso de RxJava y RxAndroid en el proyecto

Capa de Presentaci贸n

7

Introducci贸n a la capa de presentaci贸n

8

Implementaci贸n de la capa de presentaci贸n

9

Soluci贸n del reto

Capa de Casos de Uso

10

Introducci贸n a la capa de casos de uso

11

Soluci贸n del reto: capa de casos de uso

Capa de Dominio

12

Introducci贸n a la capa de dominio

13

Implementaci贸n de la capa de dominio: mappers

14

Migraci贸n entidades de framework a dominio

15

Soluci贸n del reto: capa de dominio

Capa de Datos

16

Introducci贸n a la capa de datos

17

Implementaci贸n de la capa de datos: repositorio

18

Implementaci贸n de la capa de datos: fuente de datos

19

Soluci贸n del reto: capa de datos

Extras: Migraci贸n de Capa de Casos de Uso

20

Migraci贸n de la capa de casos de uso

Capa de Framework

21

Introducci贸n a la capa de framework

22

Implementaci贸n de Image Manager (Glide)

23

Implementaci贸n de Database Manager (Room)

24

Implementaci贸n de Request Manager (Retrofit)

Inyecci贸n de Dependencias

25

Introducci贸n a la inyecci贸n de dependencias

26

Implementaci贸n de Dagger (M贸dulos)

27

Implementaci贸n de Dagger (Componente)

28

Soluci贸n del reto: inyecci贸n de dependencias

Pruebas unitarias a nivel general

29

Implementaci贸n de pruebas unitarias (conceptos generales)

30

Pruebas unitarias en la capa de presentaci贸n

31

Pruebas unitarias en las capas de casos de uso y datos

Conclusiones

32

C贸mo seguir mejorando la arquitectura

Migraci贸n de la capa de casos de uso

20/32

Lectura

Para tener una idea m谩s clara de c贸mo se puede separar la l贸gica de cada nivel dependiendo de su responsabilidad, se puede migrar las clases relacionadas con los casos de uso a un nuevo m贸dulo.

Nota: Para ver el resultado de esta migraci贸n, puedes revisar el c贸digo a partir de la rama extra_use_cases_module.

Crear nuevo m贸dulo

1.- Da clic derecho sobre la carpeta principal del proyecto y selecciona la opci贸n Nuevo -> M贸dulo.

modulo_8_clase_1_imagen_1.png

2.- Selecciona el tipo de m贸dulo que vas a crear como se indica en la siguiente imagen (para los casos de uso, bastar谩 crear una biblioteca de tipo Android o Android Library).

modulo_8_clase_1_imagen_2.png

3.- Nombra al nuevo m贸dulo usecases y cambia su nombre de paquete como se muestra en la siguiente imagen. Selecciona la opci贸n de finalizar.

modulo_8_clase_1_imagen_3.png

Configurar archivos build.gradle

1.- Implementa las dependencias con las que los casos de uso trabajan: los niveles de datos, entidades, Kotlin y RxJava como se muestra en el siguiente fragmento de c贸digo.

build.gradle (usecases)

dependencies {
    //Project
    implementation project(":data")
    implementation project(":domain")

    //Kotlin
    implementation kotlinLib

    //RxJava
    implementation rxJavaLib
}

2.- Agrega la dependencia de casos de uso a la aplicaci贸n como se muestra en el siguiente fragmento de c贸digo.
build.gradle (app)

dependencies {
    //Project
    ...
    implementation project(":usecases")
    ...
}

Mover casos de uso al nuevo m贸dulo

1.- Toma todos los cases de uso en el m贸dulo de app y mueve cada uno de ellos a un nuevo archivo que puedas llamar UseCases en el m贸dulo que acabas de crear.

UseCases.kt

package com.platzi.android.rickandmorty.usecases

import com.platzi.android.rickandmorty.data.CharacterRepository
import com.platzi.android.rickandmorty.data.EpisodeRepository
import com.platzi.android.rickandmorty.domain.Character
import com.platzi.android.rickandmorty.domain.Episode
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Single

class GetAllCharactersUseCase(
    private val characterRepository: CharacterRepository
) {

    fun invoke(currentPage: Int): Single<List<Character>> =
        characterRepository.getAllCharacters(currentPage)
}

class GetAllFavoriteCharactersUseCase(
    private val characterRepository: CharacterRepository
) {

    fun invoke(): Flowable<List<Character>> = characterRepository.getAllFavoriteCharacters()
}

class GetEpisodeFromCharacterUseCase(
    private val episodeRepository: EpisodeRepository
) {

    fun invoke(episodeUrlList: List<String>): Single<List<Episode>> =
        episodeRepository.getEpisodeFromCharacter(episodeUrlList)
}

class GetFavoriteCharacterStatusUseCase(
    private val characterRepository: CharacterRepository
) {

    fun invoke(characterId: Int): Maybe<Boolean> =
        characterRepository.getFavoriteCharacterStatus(characterId)
}

class UpdateFavoriteCharacterStatusUseCase(
    private val characterRepository: CharacterRepository
) {

    fun invoke(character: Character): Maybe<Boolean> =
        characterRepository.updateFavoriteCharacterStatus(character)
}

2.- Aseg煤rate de que tanto Activities y Fragments, as铆 como ViewModels, utilicen los casos de uso a partir del m贸dulo que creaste. Ejemplo: CharacterListViewModel utiliza el caso de uso GetAllCharactersUseCase a partir del m贸dulo usecases como se muestra en el siguiente fragmento de c贸digo.

CharacterListViewModel.kt

...
import com.platzi.android.rickandmorty.usecases.GetAllCharactersUseCase
...
class CharacterListViewModel(
    private val getAllCharactersUseCase: GetAllCharactersUseCase
): ViewModel() {
...
}

Podemos llegar a la conclusi贸n de que, al separar parte de nuestra l贸gica en distintos m贸dulos o paquetes, tienes un panorama m谩s amplio de las clases que se llevan a cabo en tus proyectos, y de esa manera, se vuelve m谩s f谩cil agregar, modificar o quitar funcionalidades.

Aportes 2

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Hola! si debo dar formato a unos datos, por ejemplo fecha o moneda, esto lo deber铆a hacer en el UseCase o en el ViewModel?

Otra pregunta, cada UseCase es la clase y el m茅todo invoke solamente? o puede haber un UseCase con multiples m茅todos?