코루틴으로 기존 프로그램 구조를 변경하다가, DI에 대해 다시 재정리가 필요할 것 같아서 재정리..합니다
DI (Dependency Injection) 의존성 주입
직접 객체를 생성하지 않고, 외부로부터 주입받는 방법 (객체의 의존성을 주입)
왜 이런 개념을 사용해야하는지 알아보겠습니다 (공식문서 참조)
의존성을 주입하지 않는 예시(클래스에서 인스턴스를 직접 생성)
class Car {
private val engine = Engine()
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.start()
}
위 코드에서의 문제점은
😱 Car, Engine이 너무 밀접하게 연결됨 (테스트가 어려움)
😱 Car에서 Engine을 구성하기 때문에 Gas, Electric Engine에 동일한 Car 클래스를 재사용하지 못하고 두 가지 유형의 Car 클래스를 생성해야합니다 -> 너무 비효율적..
📌 DI의 필요성
- 테스트의 용이성을 위해
- Refactoring의 편의성 (코드 재사용성)을 위해
📌 Android에서의 DI 2가지 방법
1. 생성자 삽입
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}
fun main(args: Array) {
val engine = Engine()
val car = Car(engine)
car.start()
}
class Car (private val engine: Engine) {...}
Car클래스에서 Engine 객체를 직접 생성하지 않고, Engine 객체를 생성자로 받고있습니다
생성자로 주입받으면서 Car 클래스의 재사용성, Car 클래스의 테스트 용이성이 해결되었습니다 :)
Car클래스의 생성과 동시에 Engine을 생성하는 경우도 있지만, 그렇지 않은 경우엔 아래의 방법을 사용합니다
2. 필드 삽입(setter 삽입)
class Car {
lateinit var engine: Engine
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.engine = Engine()
car.start()
}
클래스가 생성된 후에 Engine 객체를 생성합니다
지금 예제들은 간단하지만, 객체가 복잡해진다면 위와 같이 수동으로 작업하는 것이 굉장히 번거로울 수 있습니다
에러의 확률도 높아지구요 그래서 우린 보통 DI를 제공하는 라이브러리들을 사용합니다 🥹
DI 라이브러리
Dagger | Koin | Hilt | |
사용 언어 | Java, Kotlin | Kotlin | Java, Kotlin |
단점 | • 높은 러닝커브 | • 리플렉션 사용 • 의존관계 파악이 어려움 • Runtime에서 에러검출 |
• 낮은 점유율 |
장점 | • Compile 단계에서 에러검출 | • Compile 시간 단축 (별도의 Annotation 사용 x) • 낮은 러닝커브 |
• 의존관계 파악이 쉬움 • Dagger 기반 • Compile에서 에러검출 • 일부 핵심 클래스에 DI |
저는 Dagger만 사용을 해봤었는데, 이번에 프로젝트 구조를 변경하면서 Hilt를 도입해보기로 했습니다
Hilt의 단점은 아직 낮은 점유율, 많은 앱에서 사용하지 않는다고 생각했었는데
최근에 보니 Koin -> Hilt로 변경하는 사례들이 많은 것 같아요
https://blog.banksalad.com/tech/migrate-from-koin-to-hilt/
저도 Hilt에 대해선 전혀 모르기 때문에 다음 포스팅부터는 본격적인 DI 돌입 전, 코드랩을 통해 Hilt를 먼저 공부해보겠습니다 :)
'📱 Android' 카테고리의 다른 글
[Android] SOLID 원칙 (0) | 2023.01.08 |
---|---|
[Hilt] 코드랩으로 Hilt 익히기 # 1 (0) | 2023.01.07 |
[Android] Custom Spinner (0) | 2022.08.09 |
[Android] Custom Rating Bar (0) | 2022.08.04 |
[Android] RecyclerView - MultiViewHolder(2) (0) | 2022.07.13 |