Item5. 자원을 직접 명시하지 말고, DI를 통해 객체를 주입받자
의존관계에 있는 class를 직접 명시하는 방식(static field)은 변경에 유연성을 가지기 힘들다. 그렇다면 어떤 구조가 적합할까?
많은 class는 다른 class들과 의존관계를 갖는다.
이때 정적 유틸리티성 class로 의존관계를 맺는 것을 자주 볼 수 있다 (Item4)
예를 들면 아래의 Spellchecker class는 Dictionary class와 의존관계를 가진다.
1 | public class SpellChecker |
또는 singleton으로 구현되어 있는 경우도 자주 볼 수 있다.
1 | public class SpellChecker { |
위 두 방식의 단점은 변경이 용이하지 않다는 점이다.
예를 들면 Dictionary Class를 한국어용 사전, 영어용 사전…기타 등등 으로 요구사항에 변경이 생길 수도 있다.
사용하는 class에 따라 동작이 달라지는 class는 위 singleton,static 유틸리티성 class 방식이 적합하지 않다.
그렇다면 변경에 용이한 구조는 어떻게 설계해야할까?
1 | public class SpellChecker { |
Dictionary를 상속 계층구조로 잡고 하위 계층구조로 여러가지 종류의 사전이 있었을때, 외부 사전 class를 주입받을 때, 상위 type에 의존하도록 주입하는 방식이다.
이처럼 구현하면 instance를 생성하려고 할떄 원하는 하위 type으로 넘겨받아서 객체를 생성하면된다.
1 | SpellChecker spellChecker1 = new SpellChecker(koreanDictionary); |
책에서 사용하고 있는 말을 그대로 강조하여 쓰면, 다음과 같다.
의존 객체주입(Dependency Injection) 방식 : “인스턴스를 생성할 떄,생성자에 필요한 자원을 넘겨주는 방식”
의존 객체 주입 방식은 생성자, 정적팩터리,빌더패턴에 똑같이 응용이 가능하다.
의존 객체 주입 패턴의 변형으로 , 생성자에 자원 팩터리를 넘겨주는 방식이 있다
DI 패턴을 이용한 Framework 는 대표적으로 Spring이 매우 매우 유명하다.
*Factory란 호출할떄마다 특정타입의 인스턴스를 반복해서 만들어주는 객체를 말하며, 디자인패턴을 말한다. 자세한 내용 참조 (Design Pattern/Factory method Pattern)
Java 8 에서 나온 Supplier<T’> Interface가 Factory Method를 표현한 예다.
Factory Method 관련해서는 책 뒷부분에서 추가로 살펴볼 예정이다.