#05 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
의존 객체 주입, 의존성 주입(Dependency Injection)을 말합니다.
DI에 대해 알아보겠습니다.
예를 들어, 사전(dictionary)을 이용한 맞춤법 검사기(SpellChecker)를 구현한다면, 당연히 사전(dictionary)에 많이 의존할 수밖에 없습니다.
아래와 같이 정적 유틸리티 클래스나 싱글톤을 이용해서 하나의 dictionary 인스턴스를 가지고 구현할 수 있습니다.
이 코드는 dictionary를 변경할 수 없다는 단점이 있습니다.
실제 프로젝트를 하다 보면, 사전이 언어별/버전별/기타 여러 용도로 의해 달라질 수 있기에 수정이 필요합니다.
아래와 같이 dictionary를 교체하는 setDictionary(...) 메서드를 추가해도 문제가 발생할 수 있습니다.
요구 사항은 두 가지입니다.
// 요구사항
1. SpellChecker 클래스는 여러 dictionary 인스턴스를 지원해야 함.
2. 클라이언트가 원하는 dictionary 인스턴스를 사용해야 함.
이 두 가지 요구 사항을 모두 충족시킬 수 있는 간단한 패턴이 있습니다.
인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식입니다.
의존성 주입 (Dependency Injection)이라 불리는, 이 간단한 패턴을 통해 필요한 자원이 몇 개든, 의존 관계가 어떻게든 잘 동작합니다.
이전에 Dagger에서 다뤘지만, 생성자 이외에 다른 DI 구현법들도 있습니다.
생성자 주입 : 필요한 의존성을 모두 포함하는 클래스의 생성자를 만들고 그 생성자를 통해 의존성을 주입.
세터(Setter)를 통한 주입 : 의존성을 입력받는 세터(Setter) 메서드를 만들고 이를 통해 의존성을 주입.
인터페이스(Interface)를 통한 주입 : 의존성을 주입하는 함수를 포함한 인터페이스를 작성하고 이 인터페이스를 구현하도록 함으로써 실행 시에 이를 통하여 의존성을 주입.
DI를 통해 클래스의 유연성, 재사용성, 테스트 용이성에서 이점을 얻을 수 있습니다.
Effective Java 3판을 보고 있습니다.
자바 버전이 오른 내용을 다루다 보니, 이전에 봤던 2판과는 조금 차이가 있네요.
3판에서 추가된 내용 위주로 블로그에 정리할게요.