π Kotlin Flowμμ μ€λ³΅λλ DTO-Domain λ§€ν μ€μ΄κΈ°
π Kotlin Flowμμ μ€λ³΅λλ DTO-Domain λ§€ν μ€μ΄κΈ°
Kotlin Flowλ₯Ό μ¬μ©ν λ, APIλ‘λΆν° λ°μ λ°μ΄ν°λ₯Ό DTOλ‘ νμ±ν ν μ΄λ₯Ό Domain κ°μ²΄λ‘ λ³ννμ¬ μ¬μ©νλ κ²μ΄ μΌλ°μ μΈ ν¨ν΄μ λλ€. μ΄λ¬ν κ³μΈ΅ λΆλ¦¬λ μ½λμ νμ§μ λμ΄κ³ μκΈ°μΉ μμ λμμ λ°©μ§νλ λ° λμμ΄ λ©λλ€.
κ·Έλ¬λ Flow λ΄μμ λ§€λ² map μ°μ°μλ₯Ό μ¬μ©νμ¬ DTOλ₯Ό DomainμΌλ‘ λ³ννλ κ²μ λ°λ³΅μ μ΄κ³ μ€λ³΅λ μμ μ΄ λ μ μμ΅λλ€. μ΄λ₯Ό κ°μ νκΈ° μν΄ λ€μν λ°©λ²μ μλν΄λ³΄μμ΅λλ€.
π§ͺ μλ #1: μΈν°νμ΄μ€λ₯Ό νμ©ν μΌλ°ν
λ¨Όμ , DTO ν΄λμ€μ asDomain ν¨μλ₯Ό ꡬννκ³ μ΄λ₯Ό μΈν°νμ΄μ€λ‘ μΆμνν©λλ€.
interface DomainConvertible<Domain> {
fun asDomain(): Domain
}
κ·Έλ° λ€μ, Flowμ λν νμ₯ ν¨μλ₯Ό λ§λ€μ΄ λͺ¨λ DTO-Domain λ³νμ μ¬μ©ν μ μμ΅λλ€.
fun <T : DomainConvertible<R>, R> Flow<T>.mapToDomain(): Flow<R> = transform { emit(it.asDomain()) }
μ₯μ :
- λͺ¨λ DTO ν΄λμ€μ asDomain ꡬνμ κ°μ νμ¬ μΌκ΄μ±μ μ μ§ν μ μμ΅λλ€.
- μΌλ°νλ μ°μ°μλ₯Ό ν΅ν΄ μ½λ μ€λ³΅μ μ€μΌ μ μμ΅λλ€.
λ¨μ :
- λͺ¨λ DTO ν΄λμ€μ μΈν°νμ΄μ€λ₯Ό ꡬνν΄μΌ νλ―λ‘ μ½λκ° λ³΅μ‘ν΄μ§ μ μμ΅λλ€.
- λ§€ν ν¨μκ° DTO ν΄λμ€ λ΄λΆμ μμΉνμ¬ κ°λ μ±μ΄ λ¨μ΄μ§ μ μμ΅λλ€.
π§ͺ μλ #2: νμ₯ ν¨μλ₯Ό νμ©ν λΆλ¦¬
μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ§ μκ³ , DTOμ Flowμ λν νμ₯ ν¨μλ₯Ό λ³λμ νμΌμ μ μνμ¬ λ§€ν λ‘μ§μ λΆλ¦¬ν μ μμ΅λλ€.
fun UserDto.asDomain(): User {
return User(id = id ?: 0, name = name ?: "")
}
fun Flow<UserDto>.mapToDomain(): Flow<User> = map { it.asDomain() }
μ₯μ :
- λ§€ν λ‘μ§μ DTO ν΄λμ€ μΈλΆμ μ μνμ¬ κ°λ μ±μ΄ ν₯μλ©λλ€.
- νμν κ²½μ°μλ§ νμ₯ ν¨μλ₯Ό μ μνμ¬ μ μ°νκ² μ¬μ©ν μ μμ΅λλ€.
λ¨μ :
- λͺ¨λ DTOμ λν΄ λ³λμ νμ₯ ν¨μλ₯Ό μμ±ν΄μΌ νλ―λ‘ κ΄λ¦¬κ° λ²κ±°λ‘μΈ μ μμ΅λλ€.
π§ͺ μλ #3: μ λ€λ¦μ νμ©ν λ¨μΌ νμ₯ ν¨μ
λͺ¨λ DTO-Domain λ³νμ νλμ μ λ€λ¦ νμ₯ ν¨μλ‘ μ²λ¦¬ν μ μμ΅λλ€.
inline fun <reified T, R> Flow<T>.mapToDomain(): Flow<R> = map {
when (T::class) {
UserDto::class -> (it as UserDto).asDomain() as R
// λ€λ₯Έ DTO-Domain λ§€ν μΆκ°
else -> throw IllegalArgumentException("Unknown type")
}
}
μ₯μ :
- λ¨μΌ νμ₯ ν¨μλ‘ λͺ¨λ DTO-Domain λ³νμ μ²λ¦¬ν μ μμ΅λλ€.
- μ½λ μ€λ³΅μ μ΅μνν μ μμ΅λλ€.
λ¨μ :
- ν΄λμ€ νμ μ λͺ μμ μΌλ‘ νμΈν΄μΌ νλ―λ‘ μ μ§λ³΄μκ° μ΄λ €μΈ μ μμ΅λλ€.
- μλ‘μ΄ DTO-Domain λ§€νμ μΆκ°ν λλ§λ€ when μ μ μμ ν΄μΌ ν©λλ€.
β κ²°λ‘
κ° μ κ·Ό λ°©μμ μ₯λ¨μ μ΄ μμΌλ©°, νλ‘μ νΈμ κ·λͺ¨μ νμ μ νΈλμ λ°λΌ μ μ ν λ°©λ²μ μ ννλ κ²μ΄ μ€μν©λλ€. μ°λ¦¬ νμ κ²°κ΅ κ°μ₯ λ¨μν map μ°μ°μμ DTOμ λν νμ₯ ν¨μλ₯Ό μ¬μ©νλ λ°©λ²μ μ ννμ΅λλ€. μ΄ λ°©λ²μ λͺ μμ μ΄κ³ μ΄ν΄νκΈ° μ¬μ°λ©°, μ μ§λ³΄μ μΈ‘λ©΄μμλ μ 리νλ€κ³ νλ¨νμ΅λλ€.
π μΆμ²
Florent Blot, Redundant DTO-Domain Mapping in Kotlin Flow (Medium)