๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ๊ฐœ๋ฐœ์ž ์ด์•ผ๊ธฐ/์•ˆ๋“œ๋กœ์ด๋“œ ์‚ฝ์งˆ๊ธฐ

DI(์˜์กด์„ฑ ์ฃผ์ž…)์€ ๋ฌด์—‡์ธ๊ฐ€? ๊ทธ๋ฆฌ๊ณ  Koin DI๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณผ์ •

by ์ •์„ ํ•œ 2022. 9. 14.
728x90
๋ฐ˜์‘ํ˜•

์ €๋ฒˆ์˜ MVVM๊ณผ ๊ฐ™์ด ๋งŽ์€ ์‹ค๋ฌด ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” Dependency Injection์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Andorid์—์„œ๋„ ์ข‹์€ App Architecture๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋Š” ์›์น™์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋“ค DI๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ข‹์€ App Architecture๋ฅผ ์œ„ํ•ด์„œ AACํŒจํ„ด์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ DI๋„ ๊ฐ™์€ ๋ชฉ์ ์„ ์œ„ํ•ด์„œ ์ ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ
  • ๋ฆฌํŒฉํ† ๋ง์˜ ์šฉ์ด์„ฑ
  • ํ…Œ์ŠคํŠธ ํŽธ์˜์„ฑ

Android์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ œ์‹œํ•˜๋ฉด์„œ DI์— ๋Œ€ํ•˜์—ฌ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

class Car {
    private val engine = Engine()
    fun start() {
        engine.start()
    }
}

fun main(args: Array) {
    val car = Car()
    car.start()
}
class Car(private val engine: Engine) {
    fun start() {
        engine.start()
    }
}

fun main(args: Array) {
    val engine = Engine()
    val car = Car(engine)
    car.start()
}

์™ผ์ชฝ ์ฝ”๋“œ์™€ ์˜ค๋ฅธ์ชฝ ์ฝ”๋“œ์˜ ์ฐจ์ด์ . ๊ทธ๊ฒƒ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์•„๋Š” ๊ฒƒ์ด DI์— ๋Œ€ํ•ด์„œ ๋” ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ๋”ฐ๋กœ๋”ฐ๋กœ ์ฝ”๋“œ๋งŒ ๋ฐ”๋ผ๋ณธ๋‹ค๋ฉด,
”๋ญ๊ฐ€ ๋‹ค๋ฅธ๊ฑฐ์•ผ? ๊ฒฐ๊ตญ Engineํด๋ž˜์Šค ์™€ Carํด๋ž˜์Šค๋ฅผ mainํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ ์•„๋‹ˆ์•ผ?”

 

์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜์‹ค ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทผ๋ณธ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด ๊ฐ™์€ ๊ฒฐ๊ณผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, DI ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๋Š” ๋‹จ์–ด์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.

์ œ๊ฐ€ ์ฝ”๋“œ์—์„œ ๋ฐ‘์ค„ ๊ทธ์€ ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๋ณด์‹œ๋ฉด, Car Class๋‚ด๋ถ€์—์„œ Engine Class๋ฅผ ์ •์˜ํ•˜๋А๋ƒ, ํ˜น์€ mainํ•จ์ˆ˜ ๋‚ด์—์„œ Engine Class์™€ Car Class๋ฅผ ์ •์˜ํ•ด์„œ Car Class์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Engine Class๋ฅผ ๋„˜๊ฒจ์ฃผ๋А๋ƒ์˜ ์ฐจ์ด์ ์„ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Car Class์— Engine ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด DI ์ข…์†์„ฑ ์‚ฝ์ž…์ž…๋‹ˆ๋‹ค. Car Class๋‚ด๋ถ€์—์„œ Engine ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Engine ๊ฐ์ฒด ์ž์ฒด๋ฅผ ์ƒ์„ฑ์ž์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด Car๋Š” Engine์— ์ข…์†๋œ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒํƒœ์—์„œ๋Š” Engine Class์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ƒ๊ธฐ๊ฑฐ๋‚˜ Sub Class๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ ์šฉํ•  ๋•Œ์— Car Class์— ์˜ํ–ฅ์ด ์—†์ด ์ฝ”๋“œ๋ฅผ ์žฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋งŒ ๋ณ€๊ฒฝํ•ด์„œ Car Class์— ์ „๋‹ฌํ•ด ์ฃผ๋ฉด ๋˜๋‹ˆ๊นŒ์š”.

์‹ค์ œ Android ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์˜์กด์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ จ ๋‚ด์šฉ๋“ค์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ ์ฒ˜๋Ÿผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„ํ•œ ์ข…์†์„ฑ ์ฃผ์ž… ์ฝ”๋“œ๋ฅผ ์ˆ˜๋™ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋งŽ์ด ๋“ค์–ด๋ณด์…จ์„ Dagger, KoinDI ๊ทธ๋ฆฌ๊ณ  ์š”์ฆ˜ Android์—์„œ ๋งŽ์ด ๋ฐ€๊ณ  ์žˆ๋Š” Hilt ํ”„๋ ˆ์ž„์›Œํฌ ๋“ฑ์„ ์„ ํƒํ•˜์—ฌ DI์™€ ๊ด€๋ จํ•œ ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ €์˜ ๊ฐœ์ธ์ ์ธ ๊ฒฝํ—˜์œผ๋กœ๋Š” Koin DI๋ฅผ ํ†ตํ•ด ์ฃผ๋กœ ๊ตฌํ˜„์„ ํ•˜์˜€์—ˆ๊ณ , ํ”„๋กœ์ ํŠธ์˜ ์„ฑํ–ฅ์— ๋”ฐ๋ผ์„œ ์ ์ ˆํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ ํƒํ•˜์—ฌ ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. “๋ญ๊ฐ€ ๋” ์ข‹๊ณ  ๋‚˜์˜๋‹ค”์˜ ๊ฒฐ์ • ์‚ฌํ•ญ์ด ์•„๋‹ˆ๋ผ ๊ฐ ์ƒํ™ฉ์— ๋งž๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ •๋‹ต์ด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์— ๋Œ€๋žต์ ์ธ ํฐ ์ฐจ์ด์ ๋“ค์„ ์ž‘์„ฑํ•˜์—ฌ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

Dagger Koin DI Hilt
  • ํ•™์Šต๊ณก์„ ์ด ํผ
  • Error ๋ฐœ์ƒ์‹œ์  : CompileTime
  • Koin DI์™€ ๋™์ž‘๋ฐฉ์‹์˜ ์ฐจ์ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Error ๋ฐœ์ƒ์‹œ์ ์˜ ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒ
  • Kotlin Domain Specific Language๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ํ”„๋ ˆ์ž„์›Œํฌ
  • Kotlin ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ์—์„œ ๋น ๋ฅด๊ฒŒ ๋„์ž…๊ฐ€๋Šฅ
  • Error ๋ฐœ์ƒ์‹œ์  : RunTime
  • Dagger๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ํ”„๋ ˆ์ž„์›Œํฌ
  • Error ๋ฐœ์ƒ์‹œ์  : CompileTime

์ €๋Š” ์ €์—๊ฒŒ ๊ฐ€์žฅ ์ต์ˆ™ํ•œ Koin DI ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ €๋ฒˆ์— ์ž‘์„ฑํ–ˆ๋˜ mvvm์ฝ”๋“œ์— ์ด์–ด์„œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์›น ์‚ฌ์ดํŠธ์—์„œ ๊ฐ„๋‹จํ•œ Koin ์ ์šฉ ๋ฒ•์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋‹จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์ €๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฒ„์ „์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•˜์—ฌ koin_version์„ ํ†ตํ•ด ๋”ฐ๋กœ ์ง€์ •ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ตœ์‹  ๋ฒ„์ „์€ 3.2.0 version์ž…๋‹ˆ๋‹ค.

buildscript {
    repositories {
        mavenCentral()
    }
}
ext {
    koin_version = '3.2.0'
}
dependencies {
	...
	// Koin for Android
    implementation "io.insert-koin:koin-android:$koin_version"
}

Application() ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„์„œ ๊ทธ ๋‚ด๋ถ€์— Koin DI๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
startKoin ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Koin์„ ์‹คํ–‰์‹œํ‚ค๊ณ  modules()๋ฅผ ํ†ตํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ์— ๋กœ๋“œํ•  module ๋ชฉ๋ก์„ ์ง€์ •ํ•˜์—ฌ ์ฃผ๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

package com.dev_seonhan.mvvm

import android.app.Application
import com.dev_seonhan.mvvm.di.appModule
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin

class BaseApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        startKoin {
			androidLogger()
            androidContext(this@BaseApplication)
            modules(appModule)
        }
    }
}

์•„๋ž˜์™€ ๊ฐ™์ด module์— ๋Œ€ํ•œ ๋ชฉ๋ก์„ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ ์ด๋•Œ ๋‘ ๊ฐ€์ง€์˜ ์ž‘์„ฑ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Classical DSL Way Constructor DSL Way
val appModule = module {

    // single instance of HelloRepository
    single<HelloRepository> { HelloRepositoryImpl() }

    // Simple Presenter Factory
    factory { MySimplePresenter(get()) }
}
val appModule = module {

    // single instance of HelloRepository
    singleOf(::HelloRepositoryImpl) { bind<HelloRepository>() }

    // Simple Presenter Factory
    factoryOf(::MyPresenter)
}

์•ฝ๊ฐ„์˜ ํ‘œํ˜„์˜ ์ฐจ์ด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” TextUtil Interface๋ฅผ ์ƒ์„ฑํ•˜๊ณ  TextUtilImpl class๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์œ„์™€ ๊ฐ™์ด ์ข…์†์„ฑ ์ฃผ์ž…์„ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

package com.dev_seonhan.mvvm.di

import com.dev_seonhan.mvvm.utils.TextUtil
import com.dev_seonhan.mvvm.utils.TextUtilImpl
import org.koin.dsl.module

val appModule = module {
    single<TextUtil> { TextUtilImpl() }
}

single, factory, scoped์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค์˜ ์ œ๊ณต ๋ฐฉ์‹์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜์— ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ๋“ค์„ ์ •๋ฆฌํ•˜์—ฌ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค

single factory scoped
  • ์ „์ฒด ์ปจํ…Œ์ด๋„ˆ์— ์˜์†์ ์ธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  • ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์ œ๊ณต (๋‹จ์ผ ์ธ์Šคํ„ด์Šค)
  • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ by inject() , get() ์œผ๋กœ ์š”์ฒญํ•  ์‹œ ์‹ฑ๊ธ€ํ†ค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณต
  • ์š”์ฒญํ•  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ œ๊ณต
  • Dagger์˜ Provider์™€ ๋น„์Šทํ•œ ๊ฐœ๋…
  • factory ์ปดํฌ๋„ŒํŠธ๋กœ ์ œ๊ณต๋˜๋Š” ๊ฐ์ฒด๋Š” ์ปจํ…Œ์ด๋„ˆ์— ์ €์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์ฐธ์กฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ
  • ๋ช…์‹œ๋œ scope ์ƒ๋ช…์ฃผ๊ธฐ์— ์˜์†์ ์ธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  • Dagger์˜ Scope์™€ ๋น„์Šทํ•œ ๊ฐœ๋…
  • ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋จผ์ € scope() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฒ”์œ„๋ฅผ ์ง€์ •
  • scope์˜ ์ด๋ฆ„ ์ง€์ •์„ ์œ„ํ•˜์—ฌ Qulifiernamed๊ฐ€ ํ•„์š”
    ๋ฌธ์ž์—ด ํ•œ์ •์ธ์ง€, ํƒ€์ž… ํ•œ์ •์ธ์ง€ ๊ตฌ๋ณ„
    • StringQulifier
    • TypeQulifier

ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ๋“ค์„ ์ •๋ฆฌํ•˜์—ฌ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

์œ„์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ปจํ…Œ์ด๋„ˆ์— ๋‹ด๊ธธ ๋ชจ๋“ˆ์„ single ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ lazy ํ•˜๊ฒŒ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜์˜€๋Š”๋ฐ, ์ด๊ฒƒ์„ ํ•„์š”ํ•œ ๊ณณ์—์„œ by inject(), get()ํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜ค๋ฉด ๋ฉ๋‹ˆ๋‹ค.

val mtestTextUtilFirst: TextUtil by inject()

์œ„์™€ ๊ฐ™์ด by inject()๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณ€์ˆ˜์˜ ์„ ์–ธ ์‹œ์— lazyํ•˜๊ฒŒ ํ˜ธ์ถœ ์‹œ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ , ์•„๋ž˜์— get()์„ ์ด์šฉํ•˜์—ฌ ๋ฐ”๋กœ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ด์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	val mTestTextUtilSecond: TextUtil = get()
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋ฌด์—‡์ธ์ง€, ๊ทธ๋ฆฌ๊ณ  Koin DI ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•œ DI์ ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์š”์•ฝํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.
์ด ๊ธ€์ด ๋ชจ๋“  ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ์˜ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋” ์ƒ์„ธํ•œ ๋‚ด์šฉ๋“ค์ด ํ•„์š”ํ•˜๊ฒ ์ง€๋งŒ, ๊ทธ๊ฒƒ๋“ค ๋˜ํ•œ ์ฐจ์ฐจ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

728x90
๋ฐ˜์‘ํ˜•