03
07

https://developer.android.com/training/dependency-injection?hl=en&_gl=1*1qv5x8w*_up*MQ..*_ga*MzAxOTAwMTAzLjE3MDk3ODMyNjQ.*_ga_6HH9YJMN9M*MTcwOTc4MzI2My4xLjAuMTcwOTc4MzI2My4wLjAuMA..#kotlin

 

Android์˜ ์ข…์† ํ•ญ๋ชฉ ์‚ฝ์ž…  |  Android ๊ฐœ๋ฐœ์ž  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Android์˜ ์ข…์† ํ•ญ๋ชฉ ์‚ฝ์ž… ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ์ข…์† ํ•ญ๋ชฉ ์‚ฝ์ž…(DI)์€ ํ”„๋กœ๊ทธ๋ž˜

developer.android.com

๋จผ์ € ์ข…์† ํ•ญ๋ชฉ ์ฃผ์ž… ์—†๋Š” ์Œฉ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ๋ณด์ž.

class Engine{
    fun start(){
        println("์‹œ๋™ ๊ฑธ๊ธฐ")
    }
}

class Car {
    private val engine = Engine()

    fun start() {
        engine.start()
    }
}

fun main(){
    val di = Car()
    di.start()
}

Engine์˜ ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•ด์„œ Engine์˜ instance๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํด๋ž˜์Šค ๊ฐ„ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์„ ํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ”๊ฟ”๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ”๋กœ ์ ‘๊ทผํ•˜์ง€์•Š๊ณ , ์ƒ์œ„์ปดํฌ๋„ŒํŠธ๋„ ํ•˜์œ„์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฃผ์ž…๋ฐ›๋Š” ํ˜•ํƒœ๋กœ, ์ปจํŠธ๋กค ๋ฐ˜์ „(Inversion Of Control)์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์ด ์ด๋ค„์ง„๋‹ค. 

DI?

DI๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€๋กœ ์š”์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ํด๋ž˜์Šค ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ฐ ์ข…์† ํ•ญ๋ชฉ ๋ถ„๋ฆฌ
    • ๋ฐ›์•„์˜ฌ ์ข…์† ํ•ญ๋ชฉ์„ ์‰ฝ๊ฒŒ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค. ํด๋ž˜์Šค๊ฐ€ ๋” ์ด์ƒ ์ข…์† ํ•ญ๋ชฉ ์ƒ์„ฑ ๋ฐฉ๋ฒ•์„ ์ œ์–ดํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋ชจ๋“  ๊ณณ์—์„œ ๊บผ๋‚ด ์“ธ ์ˆ˜ ์žˆ๋‹ค.(์ปจํŠธ๋กค ๋ฐ˜์ „)
  • ๋ฆฌํŒฉํ„ฐ๋ง ํŽธ์˜์„ฑ
    • ์ข…์† ํ•ญ๋ชฉ์„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ  ๊ตฌํ˜„ ์„ธ๋ถ€์ •๋ณด๋กœ ์ˆจ๊ฒจ์ง€์ง€ ์•Š๊ณ (ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ) ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ๊ฐ„ ๋˜๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ํŽธ์˜์„ฑ
    • ํด๋ž˜์Šค๋Š” ์ข…์† ํ•ญ๋ชฉ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ…Œ์ŠคํŠธ ์‹œ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„์„ ์ „๋‹ฌํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ชจ๋“  ์‚ฌ๋ก€๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด์ง„ ์•Š์•„์„œ ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” ๊ฒฝํ—˜ํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค...

์ปจํŠธ๋กค ๋ฐ˜์ „?

์ปจํŠธ๋กค ๋ฐ˜์ „์€ ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜๋กœ, ์˜์กด์„ฑ์˜ ์ œ์–ด ํ๋ฆ„์„ ์—ญ์ „์‹œํ‚ด์œผ๋กœ์จ ์‹œ์Šคํ…œ์˜ ๋ชจ๋“ˆํ™”์™€ ์œ ์—ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์ œ์–ด ํ๋ฆ„์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์˜์กดํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ์ปจํŠธ๋กค ๋ฐ˜์ „์„ ์‚ฌ์šฉํ•˜๋ฉด ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ด๋‚˜ ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ œ์–ด๋ฅผ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ์ง์ ‘ํ•˜์ง€ ์•Š๊ณ , ๋Œ€์‹  ์™ธ๋ถ€์—์„œ ์ด๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•œ๋‹ค.

flowchart TD
    Hilt--> UseCase
    Hilt <--> repo

์ƒ์„ฑ์ž ์ฃผ์ž… / ํ•„๋“œ ์ฃผ์ž…์œผ๋กœ ๋‚˜๋ˆ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

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

fun main(){
    val engine = Engine()
    val di = Car(engine)
    di.start()
}

์ƒ์„ฑ์ž์ฃผ์ž…์€ Engine์„ ์ƒ์„ฑ์ž๋กœ ๋ฐ›์•„์„œ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ engine์˜ start ๋ฉ”์„œ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. Car์˜ ์ข…์†ํ•ญ๋ชฉ์ธ Engine์„ ์ƒ์„ฑ์ž๋กœ ์ฃผ์ž…๋ฐ›์€ ์ฝ”๋“œ๋‹ค. ⇒ ์ƒ์„ฑ์ž ์ฃผ์ž…

class Engine {
    fun start() {
        println("Engine started")
    }
}

class Car {
    lateinit var engine: Engine

    fun start() {
        engine.start()
    }
}

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

ํ•„๋“œ ์ฃผ์ž…์€ ์ƒ์„ฑ์ž๋กœ ์ ‘๊ทผํ•˜์ง„ ์•Š์ง€๋งŒ ์ข…์†ํ•ญ๋ชฉ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•ด์ค˜์•ผํ•œ๋‹ค. ์ข…์†ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— car์˜ ๋ฉค๋ฒ„์— ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๋Š” ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผํ•œ๋‹ค.

 

์ด์ „ ๊นŒ์ง€๋Š” ์ˆ˜๋™์œผ๋กœ ์ข…์†ํ•ญ๋ชฉ์„ ์ง์ ‘ ์ฃผ์ž…, ๊ด€๋ฆฌํ–ˆ๋‹ค. ⇒ ์ข…์†ํ•ญ๋ชฉ์ด ๋งŽ์•„์ง€๊ฑฐ๋‚˜ ์ข…์† ํ•ญ๋ชฉ์„ ์ „๋‹ฌํ•˜๊ธฐ ์ „์— ๊ตฌ์„ฑํ•  ์ˆ˜ ์—†์„ ๋•Œ๋Š” ๊ด€๋ฆฌ๊ฐ€ ๋งค์šฐ ๊นŒ๋‹ค๋กœ์›Œ์ง„๋‹ค.(์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒ๊ฐํ•ด์„œ ์งœ์•ผ๋œ๋‹ค.) ํŠนํžˆ ์ข…์†ํ•ญ๋ชฉ์„ lazyํ•˜๊ฒŒ ์„ ์–ธํ–ˆ์œผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด๋‹น ์ข…์† ํ•ญ๋ชฉ์˜ ์ „์ฒด ๊ธฐ๊ฐ„์„ ๊ด€๋ฆฌํ•˜๋Š” ๋งž์ถค ์ปจํ…Œ์ด๋„ˆ(๋˜๋Š” ์ข…์† ํ•ญ๋ชฉ ๊ทธ๋ž˜ํ”„)๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค. ์ด๊ฒŒ ๊นŒ๋‹ค๋กœ์šด๋ฐ, ์ด๊ฑธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ•œํ…Œ ๋„˜๊ธฐ๋Š”๊ฒŒ Dagger, Hilt๋‹ค.

 

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ด€๋ฆฌํ•˜๋ ค๋ฉด ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์„œ๋น„์Šค ๋กœ์ผ€์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ฑฐ๊ธฐ์„œ ์ข…์†ํ•ญ๋ชฉ์„ ๋ฐ›์•„์˜ค๋Š” ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

object ServiceLocator { //singleton์œผ๋กœ ์ดˆ๊ธฐํ™”๋จ.
    fun getEngine(): Engine = Engine()
}

class Car {
    private val engine = ServiceLocator.getEngine()

    fun start() {
        engine.start()
    }
}

fun main(args: Array){

}

์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์ƒ์„ฑํ•ด์„œ ์“ฐ๋‹ˆ๊นŒ ์–ผํ•๋ณด๊ธฐ์—” ํŒฉํ† ๋ฆฌํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฝค ๋ถ„๋ฆฌ๋œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ๋ฌธ์ œ๋Š” ์ข…์† ํ•ญ๋ชฉ์ด API ๋…ธ์ถœ ์˜์—ญ(์ธํ„ฐํŽ˜์ด์Šค)์ด ์•„๋‹Œ ํด๋ž˜์Šค ๊ตฌํ˜„์—์„œ ์ธ์ฝ”๋”ฉ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. object๋Š” ํด๋ž˜์Šค ์„ ์–ธ๊ณผ ๋™์‹œ์— ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค๊ฐ€ ์™ธ๋ถ€์—์„œ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๊ธฐ๊ฐ€ ๋” ์–ด๋ ค์›Œ์ง€๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ Car ๋˜๋Š” ์„œ๋น„์Šค ๋กœ์ผ€์ดํ„ฐ์—์„œ ์ข…์† ํ•ญ๋ชฉ ์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ฐธ์กฐ๊ฐ€ ์‹คํŒจํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋˜๋Š” ํ…Œ์ŠคํŠธ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”! ๋กœ๊ทธ์ธ ์•ˆํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค ^_^

 

๋ฐ˜์‘ํ˜•
COMMENT