의존성
- 참고자료
- 의존성은 언제 발생하는가?
- A 클래스의 하나의 object가 적절히 동작하기 위해 또다른 클래스의 object를 필요로 할 때 발생한다.
-
영화관을 생각하며 다음의 코드를 보자. ```kotlin class MovieTheatre {
var screen: Screen
var projector: Projector
var movie: Movieinit {
screen = Screen()
projector = Projector()
movie = Movie()
}fun playMovie() {
System.out.println(“Playing movie now”)
}
}
```
- 초기화 코드에서
- MovieTheatre는 그것의 dependency들(Screen, Projector, Movie)을 초기화한다.
- 이때 우리는 클래스와 그것의 dependency들과 밀접한 관계를 맺도록 만들게 된다.
- 따라서, 새로운 MovieTheatre를 만들 때 마다, 각각의 Screen과 Projector, Movie 인스턴스를 만들어야 한다.
- 하지만 문제는 우리가 이 객체를 만들고 사용하는 것에 있어 모두 개발해야하는 것이다.
- 일반적으로 class를 만들 땐 객체를 만드는 것과 사용하는 것을 구분해야 한다.
- 위의 경우를 생각해보자.
- 만일 영화관 객체가 Projector를 가졌다고 하자.
- 이 projector는 코드 내에서 초기화가 이루어 지므로 새로운 유형을 가질 수 없는 하나의 projector밖에 쓸 수 없을 것이다.
-
8mm 프로젝터로 선언했다가 이후에 16mm 프로젝터로 바꾸긴 힘들다는 의미
-
- 이렇게 되면 이 MovieTheatre 클래스는 프로젝터 하나 때문에 새로운 클래스를 만들어야 하며
- 재사용성을 보장할 수 없게 된다.
- 또한 MovieTheater 클래스가 너무 커지기에 하나의 객체에서 오류가 났을 때 어디서 오류가 났는지 찾기도 어렵다.
- 즉, 단위테스트가 힘들어진다.
- 위의 이유로 클래스 간의 종속성을 유연하게 만들어줄 필요가 있다.
- 때문에 Android에서는 종속 항목 삽입을 권장하고 있으며 여러 프레임워크로 제공된다.
- 위의 문제점을 통한 장점과 정의 정리하면 다음과 같다.
의존성 주입이란
- 의존성은 클래스의 객체 형태고, 의존성 주입은 외부에서 객체를 주입하는 걸 말한다
- 의존성 주입은 인터페이스를 활용해서 수행할 수 있다
- 의존성 주입 시 액티비티, 프래그먼트가 객체를 공유해 사용할 수 있다
의존성 주입의 장점
- 클래스 재사용 및 종속 항목 분리
- 종속 항목 구현을 쉽게 분리할 수 있다.
- 컨트롤 반전으로 인해 코드 재사용이 개선되었으며 클래스가 더 이상 종속 항목 생성 방법을 제어하지 않지만 대신 모든 구성에서 작동한다
- 리팩토링 편의성
- 종속 항목은 API 노출 영역의 검증 가능한 요소가 되므로 구현 세부정보로 숨겨지지 않고, 객체 생성 타임 또는 컴파일 타임에 확인할 수 있다
- 테스트 편의성
- 클래스는 종속 항목을 관리하지 않으므로 테스트 시 다양한 구현을 전달해 모든 사례를 테스트할 수 있다
Koin과 Hilt 그리고 Dagger
- 의존성 주입 프레임워크는 많이 쓰이는 것이 3가지가 있다.
- Koin
- Hilt
- Dagger
Dagger2
장점
- 강력하고 빠른 의존성 주입 프레임워크이다.
- 컴파일 타임에 DI 코드들을 생성한다.
- 따라서 런타임 성능이 좋다.
- 리플렉션을 사용하지 않음
- 자원 공유의 단순화
- 라이브러리 크기가 작다.
단점
- 학습하기가 매우 어려움
- 간단한 프로그램에는 의존성 관련한 내용을 사용하기에 부담이 크다.
- 컴파일 시에 DI를 수행하기에 컴파일 시간이 길다.
Koin
장점
- 학습하기가 매우 쉬워 적응하기가 편함
- Kotlin 개발 환경에 도입하기 쉬움
- 어노테이션을 사용하지 않기 때문에 컴파일 시간이 단축된다.
- 런타임 시에 DI를 수행함
- ViewModel 주입을 쉽게 할 수 있는 별도의 라이브러리를 제공한다.
단점
- 런타임 시 컴포넌트가 생성되어 있지 않다면 크래시 현상이 발생함
- 런타임에 DI 수행하기에
- 런타임 성능이 좋지 않다.
- 리플렉션을 이용해 성능상 좋지 않다.
- koin.get() 함수와 같이 모듈간 의존성에 대해 신경을 쓰지 않고 인스턴스를 사용하는 경우
- 추후 멀티모듈로 전향 시 어려움을 겪을 수 있다.
- 모든 클래스가 서비스 로케이터에 종속됨
- 의존 관계 파악이 어렵다.
Hilt
장점
- Dagger2 기반의 라이브러리이다.
- 훨씬 사용하기 쉽고 표준화된 사용법을 제시함
- 프로젝트 설정 간소화
- 쉬운 모듈 탐색 및 통합
- 보일러플레이트 코드 감소
- Android Studio의 지원
- AndroidX 라이브러리의 호환
단점
- Hilt가 지원하는 안드로이드 클래스 외의 곳에서 사용하려면 부가적인 사용구를 추가해줘야한다.