๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/๊ธฐํƒ€

์˜์กด์„ฑ ์ฃผ์ž… (Dependency Injection)

interfacer_han 2024. 6. 20. 00:05

#1 ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์ด๋ž€?

#1-1 Dependent์™€ Dependency

fun main() {
    val car = Car()
    car.startCar()
}

class Car {
    private val engine = Engine()
    private val airbag = Airbag()
    private val battery = Battery()

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

Car ํด๋ž˜์Šค๋Š” Engine, Battery, Airbag ํด๋ž˜์Šค์— ์˜์กด(= Car๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฆฝ ๋ถˆ๊ฐ€)ํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๊ด€๊ณ„์—์„œ Car๋Š” Engineใ† Airbagใ† Battery์˜ Dependent๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ, Engineใ† Airbagใ† Battery๋Š” Car์˜ Dependency๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
 
์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ

๋”๋ณด๊ธฐ
/* ~ ์‹คํ–‰ ๋ฐฉ๋ฒ• ~
 * 1. https://play.kotlinlang.org์— ์ ‘์†
 * 2. ์—ฌ๊ธฐ์— ์žˆ๋Š” ์ฝ”๋“œ ๋ณต์‚ฌ
 * 3. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ๋ถ™์—ฌ ๋„ฃ๊ธฐ
 * 4. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ์žˆ๋Š” Run ๋ฒ„ํŠผ ํด๋ฆญ
 *
 * ~ ์‹คํ–‰ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ~
 * Crankshaft is ready
 * Cylinder is ready
 * Piston is ready
 * Engine is ready
 * Airbag is ready
 * Battery is ready
 * Car is ready
 */

fun main() {
    val car = Car()
    car.startCar()
}

class Car {
    private val engine = Engine()
    private val airbag = Airbag()
    private val battery = Battery()

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

class Engine {
    private val piston = Piston()

    fun startEngine() {
        piston.startPiston()
        println("${this::class.simpleName} is ready")
    }
}

class Airbag {
    fun startAirbag() {
        println("${this::class.simpleName} is ready")
    }
}

class Battery {
    fun startBattery() {
        println("${this::class.simpleName} is ready")
    }
}

class Piston {
    private val crankshaft = Crankshaft()
    private val cylinder = Cylinder()

    fun startPiston() {
        crankshaft.startCrankshaft()
        cylinder.startCylinder()
        println("${this::class.simpleName} is ready")
    }
}

class Crankshaft {
    fun startCrankshaft() {
        println("${this::class.simpleName} is ready")
    }
}

class Cylinder {
    fun startCylinder() {
        println("${this::class.simpleName} is ready")
    }
}

 

#1-2 ๊ฐ„์ ‘์  Dependency

class Engine {
    private val piston = Piston()

    fun startEngine() {
        piston.startPiston()
        println("${this::class.simpleName} is ready")
    }
}

์ด๋ฒˆ์—” Engine ํด๋ž˜์Šค๋ฅผ ์‚ดํŽด๋ณธ๋‹ค. Engine์€ Pistone ํด๋ž˜์Šค์˜ Dependent, Pistone์€ Engine์˜ Dependency๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, Car์™€ Piston์˜ ๊ด€๊ณ„๋Š” ์–ด๋–จ๊นŒ? ์„œ๋กœ๊ฐ€ ์„œ๋กœ์—๊ฒŒ ์ง์ ‘์ ์ธ Dependent ๋ฐ Dependency๋Š” ์•„๋‹ˆ์ง€๋งŒ, ๊ฐ„์ ‘์ ์ธ Dependent ๋ฐ Dependency๋ผ๊ณ ๋Š” ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
 

#1-3 ์ „์ฒด ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„

๋ณธ ๊ฒŒ์‹œ๊ธ€์—์„œ ๋‹ค๋ฃฐ ํด๋ž˜์Šค๋“ค์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ, ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์œ„์™€ ๊ฐ™๋‹ค.
 

#1-4 ์˜์กด์„ฑ ์ฃผ์ž…

์œ„์— ์žˆ๋Š” Car, Engine, Piston์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ์˜์กด์„ฑ์ด '๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ฒฐํ•ฉ'(= ๊ฐ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ๋˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ์ •์˜๋จ)๋˜์–ด ์žˆ์œผ๋ฉด ํ…Œ์ŠคํŠธ, ๋ฒ„๊ทธ ์ˆ˜์ •, ์ฝ”๋“œ ํ™•์žฅ์ด ๋งค์šฐ ์–ด๋ ต๋‹ค. ์ด๋Š” ๊ฐ ํด๋ž˜์Šค๋ผ๋ฆฌ๋Š” ๋А์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜๋ฉด์„œ, ํด๋ž˜์Šค ํ•˜๋‚˜ํ•˜๋‚˜์˜ ๋‚ด๋ถ€์—์„  ๋†’์€ ์‘์ง‘๋ ฅ์„ ์ง€๋‹Œ๋‹ค๋ผ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ๊ธฐ๋ณธ ์ฒ ์น™์„ ์ ธ๋ฒ„๋ฆฌ๋Š” ํŒจํ„ด์ด๊ธฐ๋„ ํ•˜๋‹ค. ์ด ํŒจํ„ด์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ํŒจํ„ด์ด ๋“ฑ์žฅํ–ˆ๋‹ค.
 
Dependency ์ฆ‰, Car ์ž…์žฅ์—์„œ์˜ Dependency์˜€๋˜ Engine์„ Car ํด๋ž˜์Šค์— ์ฃผ์ž…(Injection)ํ•˜๊ณ  Engine ์ž…์žฅ์—์„œ์˜ Dependency์˜€๋˜ Piston์„ Engine ํด๋ž˜์Šค์— ์ฃผ์ž…(Injection)ํ•˜๋Š” ๊ฒƒ. ์ด๊ฒƒ์ด ์˜์กด์„ฑ ์ฃผ์ž…์ด๋‹ค. '์ฃผ์ž…'์ด๋ผ๋Š” ๋‹จ์–ด์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋„ฃ๋Š”๋‹ค๋Š” ์ด๋ฏธ์ง€ ๊ทธ๋Œ€๋กœ์˜ ๊ฐœ๋…์ด ๋งž๋‹ค. ์–ด๋ ต๊ฒŒ ์ƒ๊ฐํ•  ๊ฒƒ ์—†์ด, ํด๋ž˜์Šค ๋‚ด๋ถ€๊ฐ€ ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์— Denpendency๋ฅผ ์˜ฎ๊ฒจ๋‹ค๋†“์œผ๋ฉด ๊ทธ๊ฒŒ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.
 

#2 ์˜์กด์„ฑ ์ฃผ์ž…์˜ 3๊ฐ€์ง€ ๊ตฌํ˜„ ๋ฐฉ์‹

#2-1 Constructor Injection (์ƒ์„ฑ์ž ์ฃผ์ž…)

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston(crankshaft, cylinder)
    val engine = Engine(piston)
    val airbag = Airbag()
    val battery = Battery()

    val car = Car(engine, airbag, battery)
    car.startCar()
}

class Car(
    private val engine: Engine,
    private val airbag: Airbag,
    private val battery: Battery
) {
    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

์ƒ์„ฑ์ž๋Š” ํด๋ž˜์Šค์— ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ „๋‹ฌํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ์†Œํ†ต ์ฐฝ๊ตฌ๋‹ค. ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection)์€ Dependent์˜ ์ƒ์„ฑ์ž๊ฐ€ Dependency๋ฅผ ์ธ์ž๋กœ์„œ ๋ฐ›๊ฒŒ๋” ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” Dependency Injection ์œ ํ˜•์ด๊ธฐ๋„ ํ•˜๋‹ค.
 
์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ

๋”๋ณด๊ธฐ
/* ~ ์‹คํ–‰ ๋ฐฉ๋ฒ• ~
 * 1. https://play.kotlinlang.org์— ์ ‘์†
 * 2. ์—ฌ๊ธฐ์— ์žˆ๋Š” ์ฝ”๋“œ ๋ณต์‚ฌ
 * 3. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ๋ถ™์—ฌ ๋„ฃ๊ธฐ
 * 4. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ์žˆ๋Š” Run ๋ฒ„ํŠผ ํด๋ฆญ
 *
 * ~ ์‹คํ–‰ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ~
 * Crankshaft is ready
 * Cylinder is ready
 * Piston is ready
 * Engine is ready
 * Airbag is ready
 * Battery is ready
 * Car is ready
 */

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston(crankshaft, cylinder)
    val engine = Engine(piston)
    val airbag = Airbag()
    val battery = Battery()

    val car = Car(engine, airbag, battery)
    car.startCar()
}

class Car(
    private val engine: Engine,
    private val airbag: Airbag,
    private val battery: Battery
) {
    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

class Engine(private val piston: Piston) {
    fun startEngine() {
        piston.startPiston()
        println("${this::class.simpleName} is ready")
    }
}

class Airbag {
    fun startAirbag() {
        println("${this::class.simpleName} is ready")
    }
}

class Battery {
    fun startBattery() {
        println("${this::class.simpleName} is ready")
    }
}

class Piston(
    private val crankshaft: Crankshaft,
    private val cylinder: Cylinder
) {
    fun startPiston() {
        crankshaft.startCrankshaft()
        cylinder.startCylinder()
        println("${this::class.simpleName} is ready")
    }
}

class Crankshaft {
    fun startCrankshaft() {
        println("${this::class.simpleName} is ready")
    }
}

class Cylinder {
    fun startCylinder() {
        println("${this::class.simpleName} is ready")
    }
}

 

#2-2 Method Injection (ํ•จ์ˆ˜ ์ฃผ์ž…)

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston()
    piston.setDependencies(crankshaft, cylinder)
    val engine = Engine()
    engine.setPiston(piston)
    val airbag = Airbag()
    val battery = Battery()

    val car = Car()
    car.setDependencies(engine, airbag, battery)
    car.startCar()
}

class Car {
    private lateinit var engine: Engine
    private lateinit var airbag: Airbag
    private lateinit var battery: Battery

    fun setDependencies(
        engine: Engine,
        airbag: Airbag,
        battery: Battery
    ) {
        this.engine = engine
        this.airbag = airbag
        this.battery = battery
    }

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

ํด๋ž˜์Šค์— dependency๋“ค์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ํ•จ์ˆ˜(Method)๋ฅผ ๋‘๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ

๋”๋ณด๊ธฐ
/* ~ ์‹คํ–‰ ๋ฐฉ๋ฒ• ~
 * 1. https://play.kotlinlang.org์— ์ ‘์†
 * 2. ์—ฌ๊ธฐ์— ์žˆ๋Š” ์ฝ”๋“œ ๋ณต์‚ฌ
 * 3. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ๋ถ™์—ฌ ๋„ฃ๊ธฐ
 * 4. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ์žˆ๋Š” Run ๋ฒ„ํŠผ ํด๋ฆญ
 *
 * ~ ์‹คํ–‰ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ~
 * Crankshaft is ready
 * Cylinder is ready
 * Piston is ready
 * Engine is ready
 * Airbag is ready
 * Battery is ready
 * Car is ready
 */

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston()
    piston.setDependencies(crankshaft, cylinder)
    val engine = Engine()
    engine.setPiston(piston)
    val airbag = Airbag()
    val battery = Battery()

    val car = Car()
    car.setDependencies(engine, airbag, battery)
    car.startCar()
}

class Car {
    private lateinit var engine: Engine
    private lateinit var airbag: Airbag
    private lateinit var battery: Battery

    fun setDependencies(
        engine: Engine,
        airbag: Airbag,
        battery: Battery
    ) {
        this.engine = engine
        this.airbag = airbag
        this.battery = battery
    }

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

class Engine {
    private lateinit var piston: Piston

    fun setPiston(piston: Piston) {
        this.piston = piston
    }

    fun startEngine() {
        piston.startPiston()
        println("${this::class.simpleName} is ready")
    }
}

class Airbag {
    fun startAirbag() {
        println("${this::class.simpleName} is ready")
    }
}

class Battery {
    fun startBattery() {
        println("${this::class.simpleName} is ready")
    }
}

class Piston {
    private lateinit var crankshaft: Crankshaft
    private lateinit var cylinder: Cylinder

    fun setDependencies(
        crankshaft: Crankshaft,
        cylinder: Cylinder
    ) {
        this.crankshaft = crankshaft
        this.cylinder = cylinder
    }

    fun startPiston() {
        crankshaft.startCrankshaft()
        cylinder.startCylinder()
        println("${this::class.simpleName} is ready")
    }
}

class Crankshaft {
    fun startCrankshaft() {
        println("${this::class.simpleName} is ready")
    }
}

class Cylinder {
    fun startCylinder() {
        println("${this::class.simpleName} is ready")
    }
}

 

#2-3 Field Injection (๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ์ฃผ์ž…)

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston()
    piston.crankshaft = crankshaft
    piston.cylinder = cylinder
    val engine = Engine()
    engine.piston = piston
    val airbag = Airbag()
    val battery = Battery()

    val car = Car()
    car.engine = engine
    car.airbag = airbag
    car.battery = battery
    car.startCar()
}

class Car {
    public lateinit var engine: Engine
    public lateinit var airbag: Airbag
    public lateinit var battery: Battery

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ public์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ

๋”๋ณด๊ธฐ
/* ~ ์‹คํ–‰ ๋ฐฉ๋ฒ• ~
 * 1. https://play.kotlinlang.org์— ์ ‘์†
 * 2. ์—ฌ๊ธฐ์— ์žˆ๋Š” ์ฝ”๋“œ ๋ณต์‚ฌ
 * 3. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ๋ถ™์—ฌ ๋„ฃ๊ธฐ
 * 4. ์ ‘์†ํ•œ ํŽ˜์ด์ง€์— ์žˆ๋Š” Run ๋ฒ„ํŠผ ํด๋ฆญ
 *
 * ~ ์‹คํ–‰ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ~
 * Crankshaft is ready
 * Cylinder is ready
 * Piston is ready
 * Engine is ready
 * Airbag is ready
 * Battery is ready
 * Car is ready
 */

fun main() {
    val crankshaft = Crankshaft()
    val cylinder = Cylinder()
    val piston = Piston()
    piston.crankshaft = crankshaft
    piston.cylinder = cylinder
    val engine = Engine()
    engine.piston = piston
    val airbag = Airbag()
    val battery = Battery()

    val car = Car()
    car.engine = engine
    car.airbag = airbag
    car.battery = battery
    car.startCar()
}

class Car {
    public lateinit var engine: Engine
    public lateinit var airbag: Airbag
    public lateinit var battery: Battery

    fun startCar() {
        engine.startEngine()
        airbag.startAirbag()
        battery.startBattery()
        println("${this::class.simpleName} is ready")
    }
}

class Engine {
    public lateinit var piston: Piston

    fun startEngine() {
        piston.startPiston()
        println("${this::class.simpleName} is ready")
    }
}

class Airbag {
    fun startAirbag() {
        println("${this::class.simpleName} is ready")
    }
}

class Battery {
    fun startBattery() {
        println("${this::class.simpleName} is ready")
    }
}

class Piston {
    public lateinit var crankshaft: Crankshaft
    public lateinit var cylinder: Cylinder

    fun startPiston() {
        crankshaft.startCrankshaft()
        cylinder.startCylinder()
        println("${this::class.simpleName} is ready")
    }
}

class Crankshaft {
    fun startCrankshaft() {
        println("${this::class.simpleName} is ready")
    }
}

class Cylinder {
    fun startCylinder() {
        println("${this::class.simpleName} is ready")
    }
}

 

#3 ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ ๋ชจ์Œ

dependecyInjection.zip
0.00MB

์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „ + ์˜์กด์„ฑ ์ฃผ์ž…์˜ 3๊ฐ€์ง€ ์œ ํ˜•

 

#4 ์š”์•ฝ

์˜์กด์„ฑ์€ ์ฃผ์ž…์€ '๋…ธ์ถœ'์˜ ๋ฌธ์ œ๋‹ค.

 

#5 ์ด์–ด์ง€๋Š” ๊ธ€

 

[Android] Dagger2 - ๊ธฐ์ดˆ

#1 ์ด์ „ ๊ธ€ ์˜์กด์„ฑ ์ฃผ์ž… (Dependency Injection)#1 ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์ด๋ž€?#1-1 Dependent์™€ Dependencyfun main() { val car = Car() car.startCar() } class Car { private val engine = Engine() private val airbag = Airbag() private

kenel.tistory.com

์˜์กด์„ฑ ์ฃผ์ž…์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Dagger2์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.