• Home
  • About
    • Zzu-h photo

      Zzu-h

      주니어 Android 개발자입니다.

    • Learn More
    • Email
    • Instagram
    • Tistory
    • Github
  • Posts
    • All Posts
    • All Tags
    • All Categories
  • Projects

Android: 의존성 주입

15 Jul 2022

Reading time ~2 minutes

의존성

  • 참고자료
  • 의존성은 언제 발생하는가?
    • A 클래스의 하나의 object가 적절히 동작하기 위해 또다른 클래스의 object를 필요로 할 때 발생한다.
  • 영화관을 생각하며 다음의 코드를 보자. ```kotlin class MovieTheatre {

    var screen: Screen
    var projector: Projector
    var movie: Movie

    init {
    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가 지원하는 안드로이드 클래스 외의 곳에서 사용하려면 부가적인 사용구를 추가해줘야한다.


Share Tweet +1