2 분 소요

의존성 주입을 최근에 공부하게 되면서 의존성 주입에 대한 개념을 알아보려고 한다🤔


의존성 주입💉

의존성 주입(Dependency Injection)은 객체지향 프로그래밍을 하게 되면 한번씩 들어볼 수 있는 용어이다.

일반적으로 객체생성을 하게되면 사용할 클래스 내에서 객체를 생성하여 사용하지만, DI는 외부에서 생성된 객체를 주입 을 받는다.

📍의존성 주입: 외부에서 생성된 객체를 주입한다.

일반적인 예시

스마트폰이라는 객체가 있고 스마트폰에는 배터리, 유심칩, 메모리카드가 있다고 하자. 이를 일반적인 객체생성을 하게 되면 아래와 같을 것이다.

class SmartPhone {

    init {
        val battery = Battery()
        val simCard = SIMCard()
        val memoryCard = MemoryCard()
    }

    fun start() {
        Log.i("TAG", "스마트폰 동작!")
    }
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val smartPhone = SmartPhone()
        smartPhone.start()
    }
}

이렇게 해서 스마트폰을 생성하여 사용하더라도 문제없이 동작을 한다.

여기서 만약 배터리를 다른 용량의 배터리로 교체를 하려고 한다면 스마트폰 객체의 코드에서 다른 배터리 객체 로 바꿔야할 것이다.

위의 간단한 예시에서는 한줄의 코드만 바꾸면 되지만 의존 관계가 복잡해 진다면 바꿔야 할 코드가 굉장히 많아지고 또한 어느 패키지에 있는 클래스를 바꿔야할지 등 코드 수정이 굉장히 힘들어질것이다😨

생성자 주입(constructor Injection) 사용

📍생성자를 통해 의존하는 객체를 주입하는 방법

스마트폰과 부품들간의 결합도를 느슨하게 하기위하여 예시의 코드를 변경해보자.

class SmartPhone(val battery: Battery, val simCard: SIMCard, val memoryCard: MemoryCard) {

    fun start() {
        Log.i("TAG", "스마트폰 동작!")
    }
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val battery = Battery()
        val simCard = SIMCard()
        val memoryCard = MemoryCard()
        val smartPhone = SmartPhone(battery, simCard, memoryCard)
        smartPhone.start()
    }
}

이렇게 스마트폰을 생성을 하게되면 다른 용량이 큰 배터리로 교체를 하더라도 새로운 배터리 객체를 생성하여 스마트폰에 주입 을 할 수 있다. 이렇게 생성자를 통하여 의존성 주입을 하는 방법을 생성자 주입 이라이고 한다.

필드 주입(Field Injection) 사용

📍객체를 초기화한 후 의존하는 객체로 주입하는 방법

class SmartPhone {
    lateinit var battery: Battery
    lateinit var simCard: SIMCard
    lateinit var memoryCard: MemoryCard

    fun start() {
        Log.i("TAG", "스마트폰 동작!")
    }
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val battery = Battery()
        val simCard = SIMCard()
        val memoryCard = MemoryCard()

        val smartPhone = SmartPhone()
        smartPhone.battery = battery
        smartPhone.simCard = simCard
        smartPhone.memoryCard = memoryCard
        smartPhone.start()
    }
}

위의 예시처럼 배터리, 유심카드, 메모리 카드를 생성하여 외부에서 해당 멤버변수로 직접 값을 넣어주는 방법을 필드 주입 이라고 한다.

의존성 주입의 장점

앞서 살펴본 의존성 주입을 사용한다면 클래스간의 결합도가 약해지는것을 볼 수 있었다. 이러한 클래스간의 결합도가 약해지면 얻어지는 장점들은 다음과 같다.

  • 코드의 리펙토링이 쉬워진다.
  • 코드의 재사용성이 좋아진다.
  • 코드의 가독성이 좋아진다.
  • 결합도가 약해져서 Unit testing에 용이하다.

마무리

안드로이드에서 의존성 주입은 Dagger라는 프레임워크와 kotlin 언어를 사용하면 Koin을 많이 사용한다고 한다. 최근에 안드로이드 의존성 주입에 대해서 공부를 하면서 굉장히 러닝커브가 높다는걸 느꼈다.😅(프로젝트에 적용시킬 수 있을까..)

태그: ,

카테고리:

업데이트:

맨 위로 이동 ↑

댓글남기기