주니어 개발자 성장기

아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라. 본문

Java/이펙티브 자바

아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라.

Junpyo Lee 2023. 7. 15. 16:32

의존 객체 주입(DI)

사용하는 자원에 따라 동작이 달라지는 클래스에 사용하기 적합하다.

문제 상황

  1. 자원을 직접 명시하게 되면 Mocking을 할 수가 없게된다. (엄밀히 말하면 가능은 하지만 번거롭고 바람직하지 않다.)
//SpellChecker.class

// 자원을 직접 명시하는 코드
private static final Dictionary dictionary = new DefaultDictionary();

이미 자원이 클래스가 로드되는 시점에서 무조건 생성되며 변경할 수도 없다.

 

 

 

  1. 유연성과 재사용성이 떨어진다.

예제에 나온 SpellCheckerDefaultDictionary가 아닌 KoreanDictionaryEnglishDictionary를 사용하고 싶다면 어떻게 해야 할까? 기존처럼 리소스를 고정해놓는 방식을 고수한다면 KoreanSpellChecker, EnglishSpellChecker 처럼 코드가 중복된 클래스를 별도로 만들어야 한다. 게다가, 런타임 도중에 Dictionary를 바꾸기도 어려울 것이다.

 

 

 

DI(의존성 주입)

자원을 인터페이스로 갖고 있으며 객체를 외부에서 주입하는 경우 코드가 유연하고 재사용성이 높아지게 된다. 게다가 Mocking이 가능하여 테스트도 용이해진다.

 

 

 

변형

책에서 생성자에 자원 팩터리를 넘겨 주는 것이 의존 객체 주입의 쓸만한 변형이라고 한다.

public SpellChecker(Supplier<? extends Dictionary> dictionarySupplier) {
    this.dictionary = dictionarySupplier.get();
}

그리고 위와 같이 Supplier 인터페이스를 활용하는 것이 완벽한 예라고 한다. (하지만, 자원팩토리 인터페이스를 직접 구현해서 넣는 것도 가능하다.)

 

 

 

유의할 점

의존 객체 주입은 직접 구현하면 코드를 어지럽게 만들 수 있으므로, 프레임워크를 활용하여 코드를 간결하게 유지하자.

ex) 스프링, Dagger, Guice