오늘도 더 나은 코드를 작성하였습니까?

Android의 종속 항목 삽입 본문

DI/Dagger2

Android의 종속 항목 삽입

hik14 2020. 11. 24. 09:51

종속 항목 삽입(DI)은 프로그래밍에 널리 사용되는 기법으로, Android 개발에 적합합니다.

DI의 원칙을 따르면 훌륭한 앱 아키텍처를 위한 토대를 마련할 수 있습니다.

종속 항목 삽입을 구현하면 다음과 같은 이점을 누릴 수 있습니다.

 

  • 코드 재사용 가능
  • 리팩터링 편의성
  • 테스트 편의성

종속 항목 삽입 개요

클래스에는 흔히 다른 클래스 참조가 필요합니다.

예를 들어 Car 클래스는 Engine 클래스 참조가 필요할 수 있습니다.

이처럼 필요한 클래스를 종속 항목이라고 하며, 이 예에서 Car 클래스가 실행되기 위해서는 Engine 클래스의 인스턴스가 있어야 합니다.

 

클래스가 필요한 객체를 얻는 세 가지 방법은 다음과 같습니다.

 

1. 클래스가 필요한 종속 항목을 구성합니다.  Car는 자체 Engine 인스턴스를 생성하여 초기화합니다

-  Car 클래스 내부에서 Engine 객체를 생성한다.

class Car {

    private val engine = Engine()

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

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

 

Car Engine은 밀접하게 연결되어 있습니다.

Car 인스턴스는 한 가지 유형의 Engine을 사용하므로 서브클래스 또는 대체 구현을 쉽게 사용할 수 없습니다. Car가 자체 Engine을 생성하면 Gas  Electric 유형의 엔진에 동일한 Car를 재사용하는 대신 두 개 유형의 Car를 생성해야 합니다.

 

 

2. 다른 곳에서 객체를 가져옵니다. Context getter 및 getSystemService()와 같은 일부 Android API는 이러한 방식으로 작동합니다.

- getter/setter 를 통해 Car클래스 내에 Engine을 넣어준다.

 

3. 객체를 매개변수로 제공받습니다. (종속성 삽입)

앱은 클래스가 구성될 때 이러한 종속 항목을 제공하거나 각 종속 항목이 필요한 함수에 전달할 수 있습니다.

- Car 함수또는 생성자를 통해 초기화 한다.

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

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

 

Car의 재사용 가능. Engine의 다양한 구현을 Car에 전달할 수 있습니다.

예를 들어 Car에서 사용할 ElectricEngine이라는 새로운 Engine 서브클래스를 정의할 수 있습니다. DI를 사용한다면 업데이트된 ElectricEngine 서브클래스의 인스턴스를 전달하기만 하면 되며 Car는 추가 변경 없이도 계속 작동합니다.

 

Car의 테스트 편의성. 테스트 더블을 전달하여 다양한 시나리오를 테스트할 수 있습니다. 예를 들어 FakeEngine이라는 Engine의 테스트 더블을 생성하여 다양한 테스트에 맞게 구성할 수 있습니다.

 

 

 

Android에서 종속 항목 삽입을 실행하는 두 가지 주요 방법

생성자 삽입.  즉, 클래스의 종속 항목을 생성자에 전달합니다.

 

필드 삽입(또는 setter 삽입).

Activity 및 Fragment와 같은 특정 Android 프레임워크 클래스는 시스템에서 객체화하므로 생성자 삽입이 불가능합니다.

필드 삽입을 사용하면 종속 항목은 클래스가 생성된 후 인스턴스화됩니다.

 

자동 종속 항목 삽입

Car 예에서는 종속 항목이 하나만 있었지만 종속 항목과 클래스가 많아지면 수동으로 종속 항목을 삽입하는 작업이 더 지루해질 수 있습니다. 또한 수동 종속 항목 삽입에는 다음과 같은 문제도 몇 가지 있습니다.

  • 대규모 앱의 경우 모든 종속 항목을 가져와 올바르게 연결하려면 대량의 상용구 코드가 필요할 수 있습니다. 다중 레이어 아키텍처에서는 최상위 레이어의 객체를 생성하려면 그 아래에 있는 레이어의 모든 종속 항목을 제공해야 합니다. 구체적인 예로, 실제 자동차를 만들려면 엔진, 변속기, 섀시 및 기타 부품이 필요할 수 있습니다. 그리고 엔진에는 실린더와 점화 플러그가 필요합니다.
  • 종속 항목을 전달하기 전에 구성할 수 없을 때(예를 들어 lateinit을 사용하거나 객체 범위를 앱의 흐름으로 지정할 때)는 메모리에서 종속 항목의 전체 기간을 관리하는 맞춤 컨테이너(또는 종속 항목 그래프)를 작성하고 유지해야 합니다.

종속 항목을 생성하고 제공하는 프로세스를 자동화하여 이 문제를 해결하는 라이브러리가 있습니다.

이는 두 가지 카테고리로 분류됩니다.

  • 런타임 시 종속 항목을 연결하는 리플렉션 기반 솔루션
  • 컴파일 타임에 종속 항목을 연결하는 코드를 생성하는 정적 솔루션

Dagger는 Google에서 유지 관리하며 자바, Kotlin 및 Android용으로 널리 사용되는 종속 항목 삽입 라이브러리입니다.

 

Dagger는 종속 항목 그래프를 자동으로 생성하고 관리하여 앱에서의 DI 사용을 용이하게 합니다.

또한 Guice 같은 리플렉션 기반 솔루션의 여러 개발 및 성능 문제를 해결하는 완전 정적 및 컴파일 타임 종속 항목을 제공합니다.

 

결론

종속 항목 삽입의 장점

 

클래스 재사용 가능 및 종속 항목 분리

 

- 종속 항목 구현을 쉽게 교체할 수 있습니다.

- 컨트롤 반전으로 인해 코드 재사용이 개선되었으며 클래스가 더 이상 종속 항목 생성 방법을 제어하지 않지만 대신 모든 구성에서 작동합니다.

 

리팩터링 편의성

 

- 종속 항목은 API 노출 영역의 검증 가능한 요소가 되므로 구현 세부정보로 숨겨지지 않고 객체 생성 타임 또는 컴파일 타임에 확인할 수 있습니다.

 

테스트 편의성

 

- 클래스는 종속 항목을 관리하지 않으므로 테스트 시 다양한 구현을 전달하여 다양한 모든 사례를 테스트할 수 있습니다.

 

 

종속 항목 삽입의 이점을 완전히 이해하려면 수동 종속 항목 삽입에 나와 있는 것처럼 앱에서 수동으로 시도해야 합니다.

 

'DI > Dagger2' 카테고리의 다른 글

Android app에서 Dagger 사용  (0) 2021.05.03
Dagger Basic  (0) 2020.11.30
수동 종속성 삽입  (0) 2020.11.30
Dagger2 (안드로이드 의존성 주입 프레임워크)란?  (0) 2020.08.04
의존성 주입이란?  (0) 2020.08.04