Jangan menunggu Rest API di Android App Development Bagian 2 — Contoh

Dec 30 2022
Terima kasih telah membaca bagian pertama artikel ini.
Jika Anda belum membaca artikel pertama maka baca dulu dan lanjutkan dengan artikel ini. Artikel Dasar (Bagian 1) seperti yang dijelaskan pada bagian pertama artikel ini kita akan menggunakan tiga model untuk setiap lapisan Mari kita tentukan model data DTO pengguna.

Jika Anda belum membaca artikel pertama maka baca dulu dan lanjutkan dengan artikel ini.

Artikel Dasar (Bagian 1)

Jangan menunggu Rest API di Android App Development

seperti yang dijelaskan di bagian pertama artikel ini kita akan menggunakan tiga model untuk setiap layer

  1. Model Objek Transfer Data (DTO) — untuk menangani respons API
  2. Model Entitas — untuk menangani database lokal
  3. Model Domain — untuk menangani lapisan bisnis.

Mari kita tentukan model data DTO pengguna.

data class UserDto(
    @SerializedName("id") val id: String,
    @SerializedName("firstName") val firstName: String?,
    @SerializedName("lastName") val lastName: String?,
    @SerializedName("phone") val phone: String?,
    @SerializedName("email") val email: String?
)

class UserDto

data class User(
    val id: String,
    val fullName: String,
    val phone: String,
    val email: String
)

abstract class Mapper<Domain, Dto, Entity> {

    // dto-domain mappings, mandatory to implement
    abstract fun dtoToDomain(dto: Dto): Domain
    abstract fun domainToDto(domain: Domain): Dto
    
    // dto-domain list mapping support
    fun dtoToDomain(dtoList: List<Dto>?): List<Domain> = (dtoList ?: emptyList()).map(::dtoToDomain)
    fun domainToDto(domainList: List<Domain>?): List<Dto> = (domainList?: emptyList()).map(::domainToDto)

    // entity-domain mappings, mandatory to implement
    open fun entityToDomain(entity: Entity): Domain =
        throw NotImplementedError("override and implement this method")
    open fun domainToEntity(domain: Domain): Entity =
        throw NotImplementedError("override and implement this method")

    // entity-domain list mapping support
    fun entityToDomain(domainList: List<Entity>): List<Domain> = domainList.map(::entityToDomain)
    fun domainToEntity(domainList: List<Domain>): List<Entity> = domainList.map(::domainToEntity)

    // entity-dto mappings, mandatory to implement
    open fun entityToDto(entity: Entity): Dto =
        throw NotImplementedError("override and implement this method")
    open fun dtoToEntity(dto: Dto): Entity =
        throw NotImplementedError("override and implement this method")

    // entity-dto list mapping support
    fun entityToDto(dtoList: List<Entity>): List<Dto> = dtoList.map(::entityToDto)
    fun dtoToEntity(dtoList: List<Dto>): List<Entity> = dtoList.map(::dtoToEntity)

}

class UserMapper: Mapper<User, UserDto, Unit>() {
    override fun dtoToDomain(dto: UserDto): User {
        TODO("Not yet implemented")
    }

    override fun domainToDto(domain: User): UserDto {
        TODO("Not yet implemented")
    }
}

  1. Domain — Parameter model domain pertama adalah Pengguna
  2. DTO — Parameter model DTO kedua adalah UserDto
  3. DTO — Parameter model Entitas Ketiga adalah Unit, jika Anda ingin menyimpan data di database lokal maka Anda dapat menganggap parameter ketiga sebagai Entitas

override fun dtoToDomain(dto: UserDto) = with(dto) {
    User(
        id = id,
        fullName =  "$firstName + $lastName",
        phone = phone ?: "",
        email = email ?: ""
    )
}

Tidak tahu tentang respons API, tiru saja di pemetaan

override fun dtoToDomain(dto: UserDto) =
    User(
        id = "1",
        fullName = "Gautam Singh",
        phone = "xxxxxxxxxx",
        email = "[email protected]"
    )

Juga, Anda dapat melakukan hal-hal di sini seperti -

  1. Format ulang data API Anda menjadi model domain seperti dalam bisnis saya, saya hanya memerlukan nama lengkap pengguna jadi gabungkan firstName dan secondName untuk membuat fullName
  2. fullName =  "$firstName + $lastName",
    

    phone = phone ?: "",
    

Mari kita coba gunakan mapper ini dengan use case

Sumber data jarak jauh untuk pengguna

interface UserRemoteDataSource {
    suspend fun getUsers(): List<UserDto>
}

class GetAllUserUseCase(
    private val userMapper: UserMapper,
    private val remote: UserRemoteDataSource
) {

    suspend fun invoke(): List<User> = remote.getUsers().map(userMapper::dtoToDomain)

}

class UserListViewModel(getAllUserUseCase: GetAllUserUseCase) {
    
    fun users() {
        viewModelScope.launch {
            val users = getAllUserUseCase()
        }
    }

}

komentar untuk permintaan tambahan, saya akan dengan senang hati membantu Anda.