본문 바로가기
Effective Java

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

by byeongoo 2021. 1. 14.

많은 클래스가 하나 이상의 자원(Resource)에 의존한다. 간혹 정적 유틸리티나 싱글턴에서 이러한 자원을 내부적으로 명시하고 있는 경우가 있다. 아래 예시 코드에서는 두 방식 모두 사전을 하나만 사용한다. 실전에서는 사전이 언어별로 따로 있고 특수 어휘용 사전을 별도로 두기도 하기 때문에 사전 하나로 대응 하나로 모든걸 대응한다는건 안좋은 설계이다. 

 

정적 유틸리티를 잘못 사용한 예시 코드

// 정적 유틸리티 - 잘못된 예
public class SpellChecker {
   private static final Lexicon dictionary = new Lexicon(); // 특정 자원을 명시
   
   private SpellChecker() {} // 인스턴스화 방지 - 아이템 4
   
   // ...생략...
}

싱글턴을 잘못 사용한 예시 코드

// 싱글턴 - 잘못된 예
public class SpellChecker {
   private final Lexicon dictionary = new Lexicon(); // 특정 자원을 명시

   private SpellChecker() {} // 싱글턴 보증 - 아이템 3
   public static SpellChecker INSTANCE = new SpellChecker();
   
   // ...생략...
}

이처럼 사용하하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지않다.

 

SpellChecker가 여러 자원 인스턴스를 지원해야 하며, 클라이언트가 원하는 자원을 사용해야 한다. 인스턴스를 생성할 때 생성자에 필요한 자원을 주입하는 방식으로 구현할 수 있다.

// 의존 객체 주입 방식
public class SpellChecker {
   private final Lexicon dictionary; // 특정 자원을 명시하지 않음
   
   private SpellChecker(Lexicon dictionary) {
      this.dictionary = Objects.requireNonNull(dictionary);
   } // 의존성 주입
   
   // ...생략...
}

 

의존 객체 주입 패턴의 변형으로 팩토리 메서드 패턴을 이용하여 Supplier 를 생성자의 매개변수로 넘겨주는 방식으로 구현한 방법 또한 유연한 구조를 가지게 해준다.