Prologue

의존성 주입에 대해서 알아보려고 한다. 사실, 안드로이드 개발을 시작한 지 얼마 되지 않았다면 추천하지 않는 내용이다. 관련된 개념이 어렵기 때문에 어느 정도 경험이 쌓인 사람들에게 추천하고 싶다.

의존성이란

  • 코드에서 두 모듈 간의 연결 관계
  • 두 클래스 간의 관계
  • 의존성이 크다는 것은 모듈 간의 결합도가 높다는 것을 의미한다.

[의존성이 미치는 영향은?]

  • 하나의 모듈이 변경되면 결합된 다른 모듈이 영향을 받는다.
  • 2개의 모듈일 때는 괜찮지만 최악의 경우, 모듈이 100개, 1000개,… n개일 때 하나의 모듈 변경으로 인해 n-1개의 모듈이 영향을 받는다.
  • 최악의 경우이며, 나머지 모듈이 제대로 동작하는지 검증해야 한다. 시간과 비용은 모듈의 갯수인 N만큼 들게 된다.
  • 결합도를 낮춰 모듈 간의 독립성을 높이는게 중요하다.

Dependency Injection

  • 의존성 주입이라고 하며, DI라고도 부른다.
  • 구성 요소 간의 의존 관계소스 코드 내부가 아닌 외부 설정 파일 등을 통해 정의되게 하는 디자인 패턴이다.
  • 이를 통해 객체의 생성과 사용을 분리시킬 수 있고, 재사용이 가능해진다.
  • 크게 3가지 유형이 존재한다.
    1. 생성자 주입 : 필요한 의존성을 모두 포함하는 생성자를 만들고 이를 통해 의존성을 주입한다.
    2. Setter를 통한 주입 : 의존성을 입력 받는 Setter 메소드를 만들고 이를 통해 의존성을 주입한다.
    3. Interface를 통합 주입 : 의존성을 주입하는 함수를 포함하는 인터페이스를 작성하고 이를 구현함으로써 실행시, 의존성을 주입한다.
  • 주의할 점 : 생성자 주입이 권장되지만, Activity 같은 경우 멤버 인젝션을 사용해야 한다. 이유는 Activity는 생성자를 사용하지 않기 때문이다. 생성자를 사용할 수도 있지만, onCreate()보다 먼저 실행되기 때문에 권장하지 않는다.
  • 의존성 주입의 목적
    • 모듈을 Testable하게 만들 수 있다는 점이다. 즉, 독립된 모듈에 대해 테스트 코드를 작성할 수 있다.
    • 하나의 모듈이 변경되어도 다른 모듈이 영향을 받지 않으므로 유지보수가 쉽다.
    • new를 이용한 생성자를 없앨 수 있다. 모듈 내에서 다른 모듈을 초기화하면 결합도가 높아지므로 객체 생성은 외부에서 하고 생성된 객체를 참조한다.
    • 객체 생성을 외부에서 하기 때문에 모듈의 독립성이 높아지고 모듈에 대한 테스트가 가능하며, 재사용할 가능성이 높아진다.
  • 장점
    • 클래스 간의 결합도를 낮춰 독립성을 높이므로 유지보수가 수월해진다.
    • 코드의 재사용을 높이기 때문에 작성된 모듈을 여러 곳에서 수정 없이 사용할 수 있다.
    • Mock 객체 등을 이용한 단위 테스트의 편의성을 높여준다.
    • 객체 생성을 외부에서 하면 클래스의 독립성이 높아지고 이에 따라서 클래스를 테스트 가능하게 할 수 있으며 재사용을 할 가능성도 높아진다.

A 클래스가 B 클래스를 의존할 때, B의 객체를 A가 직접 생성하지 않고 오른쪽 그림처럼 생성하여 넘겨주는 것을 의존성 주입이라고 볼 수 있다.

결국, 의존성 주입을 위해서는 객체를 생성하고 넘겨주는 외부의 무언가가 필요하다. 직접 의존성을 제공하는 Provide 형태의 클래스를 작성할 수 있고 라이브러리로 넘겨서 처리하도록 구현할 수도 있다.

Dependency Injection은 의존성이 있는 객체의 제어를 외부 Framework로 올리면서 IoC(Inversion Of Control) 개념을 구현한다. => 제 3자에 의해 정의되기 때문에 의존 관계가 역전되었다고 볼 수 있다.

Android에서 이를 지원하는 라이브러리 중 Dagger2와 Koin이 있으며, 관련 개념과 사용법은 추후에 정리할 예정이다.

결론 : 의존성 주입은 두 개 이상의 모듈(클래스)간의 결합도를 낮추기 위해 외부에서 객체 생성(new)하고 주입하는 것이다.