나만 보는 일기장

DI Framework - (1) 의존성 주입의 종류 3가지 본문

개발/Android

DI Framework - (1) 의존성 주입의 종류 3가지

Patrick0422 2021. 9. 6. 16:18
fun main() {
    makePC()
}

fun makePC(): PC {
    // ???
}

class PC() {
    // ...
}

class CPU {
    // ...
}

class GPU {
    // ...
}

class RAM {
    // ...
}

class Power {
    // ...
}

 

PC라는 클래스를 만들기 위해 CPU, GPU, RAM, Power이라는 클래스들이 필요하다고 할 때,

PC는 해당 클래스들에 대해 의존성을 가지고 있는 Dependent라고 하고,

PC를 만들 때 필요한 클래스들은 Dependency라고 한다.

 

그리고 이 부품들을 PC에 전달하는 것을 의존성 주입이라 하는데, 의존성 주입의 방법에는 크게 3가지가 있다.

1. Constructor Injection

fun makePC(): PC {
    val cpu = CPU()
    val gpu = GPU()
    val ram = RAM()
    val power = Power()
    
    val pc = PC(cpu, gpu, ram, power)
    
    return pc
}

class PC(val cpu: CPU, val gpu: GPU, val ram: RAM, val power: Power) {

}

Constructor Injection은 이름처럼 생성자를 통해 의존성을 주입하는 방식으로, 외부에서 Dependency들을 생성하여

Dependent의 생성자에 넣는 방식이다.

 

안드로이드 개발에서 보통의 경우 이 Constructor Injection을 쓰는 것을 권장한다고 한다.

 

2. Method Injection

fun makePC(): PC {
    val pc = PC()
    pc.setCPU(CPU())
    pc.setGPU(GPU())
    // ...

    return pc
}

class PC() {
    private lateinit var cpu: CPU
    private lateinit var gpu: GPU
    private lateinit var ram: RAM
    private lateinit var power: Power
    
    fun setCPU(cpu: CPU) {
        this.cpu = CPU()
    }
    fun setGPU(gpu: GPU) {
        this.gpu = GPU()
    }
    // ...
}

Method Injection은 Dependent 내부의 함수를 통해 Dependency들을 전달해주는 방식이다.

 

거의 쓰이지 않는 방식인 것 같다.

3. Field Injection

fun makePC(): PC {
    val pc = PC()

    pc.cpu = CPU()
    pc.gpu = GPU()
    // ...

    return pc
}

class PC() {
    public lateinit var cpu: CPU
    public lateinit var gpu: GPU
    public lateinit var ram: RAM
    public lateinit var power: Power
}

Field Injection은 객체를 생성한 후 객체의 파라미터에 직접 Dependency들을 전달하는 방식이다.

 

 

위 예제에서는 클래스들이 아주아주 간단하기 때문에 손수 타이핑 해서 의존성을 주입하는게 가능했지만,

실제 개발에서는 구조가 아주 복잡하기 때문에 직접 의존성 주입을 하기엔 어렵다.

 

그래서 쓰는 것이 바로 DI Framework인 Dagger/Hilt, Koin 등의 프레임워크들이다.

이들을 통해 비교적 쉽게 의존성 주입을 할 수 있게 된다.

Comments