๐Ÿค– [Android]๊ตฌ๊ธ€ ๊ถŒ์žฅ ์•„ํ‚คํ…์ฒ˜ <Domain Layer>

yeonjeenยท2024๋…„ 2์›” 11์ผ
2

Android

๋ชฉ๋ก ๋ณด๊ธฐ
2/10

Domain layer ย |ย  Android Developers

<ํ•ด๋‹น ๋‚ด์šฉ์€ ์œ„ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์˜€์Šต๋‹ˆ๋‹ค>

Domain Layer๋Š” UI Layer์™€ Data Layer ์‚ฌ์ด์— ์กด์žฌํ•˜๋ฉฐ, ์„ ํƒ์  ์š”์†Œ

๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง or ๋ทฐ๋ชจ๋ธ์—์„œ ์žฌ์‚ฌ์šฉ๋˜๋Š” ๊ฐ„๋‹จํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋“ฑ์„ ์บก์Аํ™” ๋‹ด๋‹น

๋ชจ๋“  ์•ฑ์—์„œ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๐ŸŽย ๋‚ด๊ฐ€ ๋ชฐ๋ผ์„œ ์ค€๋น„ํ•œ IT ์‚ฌ์ „
[์บก์Аํ™”] : ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)์˜ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋กœ, ๋ฐ์ดํ„ฐ์™€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋Š” ์™ธ๋ถ€์—์„œ ์ง์ ‘์ ์œผ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๊ณ , ์˜ค์ง ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค.

Domain Layer์˜ ์ด์ 

  • ์ฝ”๋“œ ์ค‘๋ณต ๋ฐฉ์ง€
  • ํด๋ž˜์Šค์˜ ๊ฐ€๋…์„ฑ ๊ฐœ์„ 
  • ์•ฑ์˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ ํ–ฅ์ƒ
  • ์ฑ…์ž„์„ ๋ถ„ํ™œํ•˜๋ฉด์„œ ๋Œ€ํ˜• ํด๋ž˜์Šค๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€

โžก๏ธย ๊ฐ๊ฐ์˜ UseCase์—์„œ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ๋งŒ ๋‹ด๋‹นํ•ด์•ผํ•˜๊ณ , ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋Š” UI Layer์™€ Data Layer์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“›ย Naming Conventions

์˜ˆ์‹œ)

FormatDateUseCase

LogOutUserUseCase

GetLatestNewsWithAuthorsUseCaseย 

MakeLoginRequestUseCase

โœจย ์˜์กด์„ฑ

์ผ๋ฐ˜์ ์ธ ์•ฑ ์•„ํ‚คํ…์ฒ˜์—์„œ UseCase๋Š” UI Layer์˜ ViewModel๊ณผ Data Layer์˜ Repository ์‚ฌ์ด์— ์กด์žฌ

โžก๏ธย UseCase๋Š” Repository ํด๋ž˜์Šค์— ์ข…์†๋˜์–ด ์žˆ์œผ๋ฉฐ, Repository์™€ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์—ฌ UI Layer์™€ ํ†ต์‹ 

class GetLatestNewsWithAuthorsUseCase(
  private val newsRepository: NewsRepository,
  private val authorsRepository: AuthorsRepository
) { /* ... */ }

์œ„์—์„œ GetLatestNewsWithAuthorsUseCase ๋Š” NewsRepository์™€ AuthorsRepository ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

UseCase๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋กœ์ง์„ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ UseCase์— ์˜ํ•ด์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

class GetLatestNewsWithAuthorsUseCase(
  private val newsRepository: NewsRepository,
  private val authorsRepository: AuthorsRepository,
  private val formatDateUseCase: FormatDateUseCase
) { /* ... */ }

์œ„์˜ ์ฝ”๋“œ์—์„œ GetLatestNewsWithAuthorsUseCase ์•ˆ์— FormatDateUseCase๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ›Ž๏ธย UseCase ํ˜ธ์ถœ in Kotlin

๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป Kotlin์—์„œย operatorย ์™€ ํ•จ๊ป˜ย invoke()ย ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์—ฌ UseCase ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

class FormatDateUseCase(userRepository: UserRepository) {

    private val formatter = SimpleDateFormat(
        userRepository.getPreferredDateFormat(),
        userRepository.getPreferredLocale()
    )

    operator fun invoke(date: Date): String {
        return formatter.format(date)
    }
}

FormatDateUseCase์˜ย invoke()ย ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ํ•จ์ˆ˜์ธ ๊ฒƒ์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. invoke()ย ๋ฉ”์„œ๋“œ๋Š” ํŠน์ •ํ•œ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— ์ œํ•œ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐœ์ˆ˜์— ์ƒ๊ด€์—†์ด ์ทจํ•˜๊ณ  ๋ชจ๋“  ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

class MyViewModel(formatDateUseCase: FormatDateUseCase) : ViewModel() {
    init {
        val today = Calendar.getInstance()
        val todaysDate = formatDateUseCase(today)
        /* ... */
    }
}

FormatDateUseCase ์„ MyViewModel์—์„œ ์œ„์™€ ๊ฐ™์ด ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋‹ค.

< invoke() ๋ฉ”์„œ๋“œ์™€ operator ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฐ‘์— ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. >

Operator overloading | Kotlin

velog

๐ŸŒ€ย ์ƒ๋ช…์ฃผ๊ธฐ

๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป UseCase๋Š” ๋”ฐ๋กœ ์ƒ๋ช…์ฃผ๊ธฐโŒ UseCase๊ฐ€ ์†ํ•ด์žˆ๋Š” ํด๋ž˜์Šค์˜ ๋ฒ”์œ„๊ฐ€ ์ ์šฉ

โžก๏ธย UI Layer์˜ ํด๋ž˜์Šค์—์„œ Service์—์„œ ๋˜๋Š”ย Applicationย ํด๋ž˜์Šค ์ž์ฒด์—์„œ UseCase๋ฅผ ํ˜ธ์ถœ

UseCase๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จ โŒย 

โžก๏ธย UseCase ํด๋ž˜์Šค์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ข…์† ํ•ญ๋ชฉ์œผ๋กœ ์ „๋‹ฌํ•  ๋•Œ๋งˆ๋‹ค ๊ทธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

๐ŸŒธย Threading

Domain Layer์— ์†ํ•˜๋Š” UseCaseํด๋ž˜์Šค๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์—์„œ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ๋Š” UI ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ ํ•˜๊ณ , ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ๋ธ”๋กœํ‚นํ•˜๋Š” ์ž‘์—…์ด ๋ฐœ์ƒํ•˜๋ฉด ์•ฑ์˜ ๋ฐ˜์‘์„ฑ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

โžก๏ธ UseCase ํด๋ž˜์Šค ๋‚ด์—์„œ๋Š” ๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ๋ธ”๋กœํ‚น ์ž‘์—…์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ํ•ด๋‹น ์ž‘์—…์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ๋ธ”๋กœํ‚น์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

class MyUseCase(
    private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) {

    suspend operator fun invoke(...) = withContext(defaultDispatcher) {
        // Long-running blocking operations happen on a background thread.
    }
}

Kotlin์˜ ์ฝ”๋ฃจํ‹ด(Coroutine)์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋‹ค.

๐Ÿ’ก MyUseCase ํด๋ž˜์Šค์˜ invoke ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ์—๋Š” ํ•ด๋‹น ์ž‘์—…์ด ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ํ˜ธ์ถœ๋˜๋”๋ผ๋„ ์‹ค์ œ ์ž‘์—…์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ๋ธ”๋กœํ‚น์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์•ฑ์˜ ๋ฐ˜์‘์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์ด ๋ฐ˜๋“œ์‹œ UseCase ํด๋ž˜์Šค ๋‚ด์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ, ํ•ด๋‹น ์ž‘์—…์ด ๋‹ค๋ฅธ ๋ ˆ์ด์–ด์—์„œ ๋” ์ ํ•ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Data Layer์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ๋ณต์žกํ•œ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•œ ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

๐Ÿงฉย ์‹คํ–‰ ๋ฐฉ๋ฒ•

์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง

UI Layer์— ์žˆ๋Š” ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ UseCase ํด๋ž˜์Šค์—์„œ ์บก์Аํ™” ๋˜์–ด์•ผ ํ•œ๋‹ค.

๊ทธ ๋กœ์ง์ด ์‚ฌ์šฉ๋œ ๋ชจ๋“  ๊ณณ์— ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋” ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ๋กœ์ง์„ ๋…๋ฆฝ์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

import java.text.SimpleDateFormat
import java.util.*

class FormatDateUseCase {

    // ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก suspend ํ•จ์ˆ˜๋กœ ์„ ์–ธ
    suspend operator fun invoke(date: Date): String {
        // ๋‚ ์งœ ํฌ๋งท ํ˜•์‹
        val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        // ์ฃผ์–ด์ง„ ๋‚ ์งœ๋ฅผ ํฌ๋งท์— ๋งž์ถฐ์„œ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜
        return dateFormat.format(date)
    }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
fun main() {
    // ํ˜„์žฌ ๋‚ ์งœ๋ฅผ ๊ฐ€์ ธ์˜ด
    val currentDate = Date()

    // FormatDateUseCase๋ฅผ ์ดˆ๊ธฐํ™”
    val formatDateUseCase = FormatDateUseCase()

    // UseCase๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‚ ์งœ ํฌ๋งทํŒ… ์ˆ˜ํ–‰
    val formattedDate = formatDateUseCase(currentDate)

    // ๊ฒฐ๊ณผ ์ถœ๋ ฅ
    println("Formatted date: $formattedDate")
}

ํ–ฅํ›„์— ๋‚ ์งœ ํ˜•์‹๊ณผ ๊ด€๋ จ๋œ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ ์ฝ”๋“œ๋ฅผ ์ค‘์•™์—์„œ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์•„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Repository ๊ฒฐํ•ฉ

News์•ฑ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

๋‰ด์Šค์™€ ์ž‘์„ฑ์ž ๋ฐ์ดํ„ฐ ์ž‘์—…์„ ๊ฐ๊ฐ ์ฒ˜๋ฆฌํ•˜๋Š”ย NewsRepositoryย ์™€ย AuthorsRepositoryย ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

NewsRepository์—์„œ ๋…ธ์ถœ๋˜๋Š”ย Articleย ํด๋ž˜์Šค์—๋Š” ์ž‘์„ฑ์ž ์ด๋ฆ„๋งŒ ํฌํ•จ๋œ๋‹ค.

โ“ย ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑ์ž์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด?

์ด๋Ÿฌํ•œ ์ •๋ณด๋Š” AuthorsRepository ์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๊ฒ ์ฃ .

์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์˜ ๋กœ์ง ์•ˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ repository๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š”GetLatestNewsWithAuthorsUseCaseย ๋ฅผ ๋งŒ๋“ค์–ด์„œ ViewModel์—์„œ ๋กœ์ง์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ๋กœ์ง์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๊ฐœ๋ณ„์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์•ฑ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๐Ÿ™…๐Ÿปโ€โ™€๏ธย Data Layer ์—‘์„ธ์Šค ์ œํ•œ

๐Ÿ’ก Domain Layer๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ์€ UI Layer์—์„œ Data Layer์— ์ง์ ‘ ์•ก์„ธ์Šคํ•˜๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด Domain Layer๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ๊ฒƒ์„ ๊ฐ•์ œ ์ ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€

๐Ÿ”ตย ์žฅ์  : Domain Layer ๋กœ์ง ์œ„ํšŒ ๋ฐฉ์ง€

Domain Layer์˜ ๋กœ์ง์„ UI Layer๊ฐ€ ์šฐํšŒํ•˜์—ฌ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—…์€ Domain Layer์˜ ๋กœ์ง์œผ๋กœ ํฌํ•จ ๋  ์ˆ˜ ์žˆ๋Š” ์˜์—ญ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๋กœ์ง์—๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ, ๊ถŒํ•œ ๋ถ€์—ฌ, ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ฐ ๋ถ„์„ ๋กœ๊น…๊ณผ ๊ฐ™์€ ๋ณด์•ˆ ๋ฐ ๋กœ๊น… ๊ธฐ๋Šฅ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ UI Layer๊ฐ€ Domain Layer๋ฅผ ์šฐํšŒํ•˜์—ฌ Data Layer์— ์ง์ ‘ ์•ก์„ธ์Šค ํ•œ๋‹ค๋ฉด, ์ด๋Ÿฌํ•œ ๋ณด์•ˆ ๋ฐ ๋กœ๊น… ๋กœ์ง์ด ์šฐํšŒ๋  ์ˆ˜ ์žˆ๋‹ค.
โžก๏ธ UI Layer๊ฐ€ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•ก์„ธ์Šคํ•œ๋‹ค๋ฉด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง์ด Domain Layer๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ์ด๋‚˜ ๊ถŒํ•œ ๋ถ€์—ฌ์™€ ๊ฐ™์€ ์ค‘์š”ํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ์ด ๋ฌด์‹œ๋  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, UI Layer๋Š” Domain Layer์˜ ๋กœ์ง์„ ์šฐํšŒํ•˜์—ฌ ์ง์ ‘ ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์•ผ ํ•œ๋‹ค. UI Layer๋Š” Domain Layer๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•˜๋ฉฐ, ๋„๋ฉ”์ธ ๋ ˆ์ด์–ด์˜ ๋ณด์•ˆ ๋ฐ ๋กœ๊น… ๋กœ์ง์ด ํ•ญ์ƒ ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์‹œ์Šคํ…œ์˜ ๋ณด์•ˆ์„ฑ๊ณผ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”ดย ๋‹จ์  : ๋ณต์žก์„ฑ ์ฆ๊ฐ€

๋‹จ์ˆœํ•œ Data Layer์— ๋Œ€ํ•œ ํ˜ธ์ถœ์ด ์žˆ์„ ๋•Œ๋„ UseCase๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์€ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’ก ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๊ณ , Data Layer์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œํ•œํ• ์ง€ ์—ฌ๋ถ€๋Š” ๊ฐœ๋ณ„ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—„๊ฒฉํ•œ ๊ทœ์น™์ด๋‚˜ ์œ ์—ฐํ•œ ์ ‘๊ทผ ๋ฐฉ์‹ ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋Š”์ง€์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.
๊ฐœ๋ฐœ์ž๋Š” ๊ฐœ๋ณ„ ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ ์ ˆํžˆ ์กฐ์ ˆํ•˜๋Š” ๋Šฅ๋ ฅ์ด ํ•„์š”ํ•˜๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€