DI는 프로그래밍에서 널리 사용되는 기법으로, Android 개발에 적합하다.
DI의 원칙을 따르면 앱 아키텍처를 위한 토대를 마련할 수 있다.
다음과 같은 이점이 있다
생성자 또는 메서드 등을 통해 외부로부터 생성된 객체를 전달받는 것
📌 특징
📌 왜 사용할까?
1. 유연성과 재사용성
2. 테스트 용이성
3. 유지보수성
4. 코드의 가독성과 이해도
5. 의존성 교체 및 관리 용이성
6. 객체 생성과 생명 주기의 관리
7. 가독성 및 추상화 증대
다음은 종속성 주입이 없는 코드 예시이다.
class Car {
private val engine = Engine()
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.start()
}
위 코드는 Car와 Engine이 강하게 결합되어 있다. Car 객체는 특정 유형의 Engine을 사용하기 때문에 만약, Gas나 Eletric 유형의 Engine이 있다고 하면, Car를 재사용할 수 없게된다.
이러한 이유로 다음 두 가지 주요 방법을 사용하여 DI를 실행할 수 있다.
의존성을 클래스의 생성자에 전달하는 것을 의미한다.
📌 장점
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}
fun main(args: Array) {
val engine = Engine()
val car = Car(engine)
car.start()
}
필드 삽입은 의존성을 클래스의 필드에 직접 주입하는 방법이다
📌 Activity 및 Fragment와 같은 특정 클래스는 시스템에서 인스턴화하므로 생성자 삽입이 불가능하다. 이런 경우 필드삽입을 사용하면 종속 항목은 클래스가 생성된 후 인스턴스화 된다.
📌 장점
📌 단점
class Car {
lateinit var engine: Engine
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.engine = Engine()
car.start()
}
📌 코드를 더 명확하게 만들고 테스트 용이성을 높이기 때문에 대부분의 경우 생성자 삽입이 권장하며 필드 삽입은 주로 DI 프레임워크를 사용할 때나 특별한 경우에 사용한다.
서비스 로케이터(Service Locator)는 객체의 위치를 찾아주는 디자인 패턴 중 하나이다. - 객체 간의 의존성을 관리하고 해결하는 데 사용
📌 장점
📌 단점
📌 대부분의 경우, DI 패턴이나 DI 프레임워크를 사용하는 것이 더 권장된다.