[DI 개념과 필요한 이유]
한 클래스는 다른 클래스를 참조해야하는 일이 빈번하다. (특히 디자인패턴을 다루면서)
예를 들어 Computer 클래스를 실행시키려면 Computer 클래스 내에서 Cpu 클래스 객체를 참조해야한다고 해보자.
이 상황에서 Computer 클래스가 Cpu 클래스에 의존한다고 한다.
이 방법에는 당장 생각나는 두 가지가 있을 것이다.
- Cpu 객체를 클래스 내부에서 직접 생성하기
Computer 클래스가 한 타입의 Cpu 객체만 사용해버린다. 즉 서브클래스를 쉽게 사용할 수 없다.
그렇다면 Intel Cpu, AMD Cpu 각각을 사용하는 Computer 클래스를 각각 만들어야 할 것이다.
Computer 에서 Cpu 객체를 직접 생성하면 테스트도 어렵게 함 - 생성자나 메소드 파라미터로 Cpu 객체를 받아오기
Computer 의 재사용성이 증가한다.
왜냐하면 Cpu 의 여러 구현체를 Computer 에 넘겨줄 수 있기 때문이다.
여기서 2번이 이번에 말하려는 DI 이다.
즉 안에서 생성해서 의존하는 것이 아니라 밖에서 '주입' 인 것이다.
[위에서 살펴본 DI 의 이점]
- 코드의 재사용성 및 decoupling of dependencies
- 리팽토링 용이성
- 테트트 용이성
- 확장성
[수작업으로 직접 DI 하는 주요한 두 가지 방식]
- Constructor Injection
말 그대로 생성자로 원하는 객체를 주입하는 방식이다. - Field Injection (or Setter Injection)
액티비티, 프래그먼트 같은 특정한 안드로이드 프레임워크 클래스들은 시스템에의해 초기화 된다.
예를 들면 앞서말한 클래스에 lateinit var 로 멤버변수로 두고, 초기화 된 후에 밖에서 접근해서 초기화해주는 방식이다.
하지만 프로젝트 규모가 커지면 많은 보일러 플레이트코드가 요구된다는 문제가 있다.
예를들면 Constructor Injection 으로 의존성을 주입하는 방식에서 서로 다른 두 가지 곳에 객체를 생성해야한다면 코드가 중복된다.
그래서 그러한 문제를 해결해주는 DI 라이브러리가 있다.
[대표 DI 라이브러리]
- Dagger
컴파일 시에 의존성을 연결하는 코드를 생성하는 Static Solution. 따라서 compile-time dependencies
compile-time correctness, runtime performance, scalability 측면에서 이득
의존성들의 그래프를 만들고 관리해줘서 DI 를 돕는다.
구글이 관리함 - Hilt
힐트는 제트팩에서 권장하는 DI 라이브러리이다.
힐트는 Dagger 위에 구축되어있다. (compile-time correctness, runtime performance, scalability 측면에서 이득)
따라서 힐트 역시 compile-time dependencies, runtime performance, scalability 라는 이점이 있다.
프로젝트에 있는 모든 안드로이드 클래스에 컨테이너를 제공하고 그들의 라이프사이클을 자동으로 관리해준다. - Koin (DI 를 하는 대체제는 Service Locator)
내가 최근 프로젝트에 적용했던 DI 라이브러리이다.
장점은 러닝커브가 낮고 모듈에서 의존성을 가진 객체와 컴포넌트를 한 눈에 알아 볼 수 있다는 것이다.
하지만 단점은 DI 관련 에러를 런타임 중에 알게된다는 점과 런타임 퍼포먼스가 있다는 이슈가있다.
또한 아래 사진은 Hilt 를 사용한 프로젝트 일부 사진인데 왼쪽 아이콘을 누르면 의존성이 어디로부터 주입되었는지 알아볼 수 있다. 하지만 Koin 은 이런 것이 없다는 것도 단점으로 다가왔다.
[수작업 의존성 주입이 아닌 라이브러리를 사용했을 때 장점]
- DI 라이브러리는 의존성 주입에 필요한 코드를 자동으로 생성해주니까 보일러플레이트 코드를 줄임
-> (가독성 up , 사소한 버그 down?) - 메모리 관리를 위해 scope 와 lifecycle 을 직접 관리할 필요가 없음
Koin 은 위의 의존성 개념과 이점을 알고 아래 공식문서만 보면 10분도 안돼서 익힐 수 있었다.
이후 상대적으로 러닝커브가 높다는 Hilt 에 관해 공부하고 사용해보면서 글을 작성하여 링크를 추가하겠다.
(여기에 링크가 추가될 것)
'Android > 이론 학습' 카테고리의 다른 글
[Android/Kotlin] Intent 에 커스텀 객체 전달하기? 직렬화, 역직렬화 Serializable 과 Parcelable, @Parcelize (0) | 2022.02.20 |
---|---|
[Android] Hilt 의 다양한 어노테이션을 알아보자 (0) | 2022.02.19 |
[Android] 안드로이드의 Background 작업 (0) | 2022.02.12 |
[Android] Activity 의 Life cycle 과 App Life cycle 을 연관지어 생각해보기 (0) | 2022.02.10 |
[Android] 안드로이드의 Processes 와 App Life-cycle (0) | 2022.02.07 |