사용하는 자원(객체, 변수 등)에 따라 동작이 달라지는 클래스 → '의존 객체 주입' 사용
in Development on Java
사용하는 자원에 따라 동작이 달라지는 클래스에는 ‘정적 유틸리티 클래스‘나 ‘싱글턴 방식‘이 적합하지 않다. 이 때에는 인스턴스를 생성할 때 생성자에 필요한 자원(객체, 변수 등)을 넘겨주는 방식인 ‘의존 객체 주입 패턴’을 사용해야 한다.
예시
맞춤법 검사기(SpellChecker)를 구현할 예정인데, 맞춤법 검사를 할 때에 사전(dictionary)가 필요하다. 하지만 어떤 언어의 맞춤법을 검사하냐에 따라서 여러 종류의 사전이 필요하다고 가정하자.
비추천) ‘정적 유틸리티’를 사용해서 구현한 경우 - 유연하지 않고 테스트하기 어렵다
// 맞춤법 검사기 기능
public class SpellChecker {
// 맞춤법 검사를 할 때 필요한 자원 -> 사전(dictionary)
private static final Lexicon dictionary = ...;
// 정적 유틸리티 클래스이므로 객체 생성 방지
private SpellChecker() {}
// 정적 메서드
public static boolean isValid(String word) { ... }
// 정적 메서드
public static List<String> suggestions(String typo) { ... }
}
비추천) ‘싱글턴’를 사용해서 구현한 경우 - 유연하지 않고 테스트하기 어렵다
// 맞춤법 검사기 기능
public class SpellChecker {
// 맞춤법 검사를 할 때 필요한 자원 -> 사전(dictionary)
private final Lexicon dictionary = ...;
private SpellChecker(...) {}
public static SpellChecker INSTANCE = new SpellChecker(...);
public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}
위 2가지 방법(정적 유틸리티, 싱글턴) 전부 사전(dictionary)을 하나만 사용하는 걸 전제로 코드를 작성한 것이라서 여러 종류의 사전을 사용하지 못한다는 것에 제약이 따른다. 즉, 유연하지 못한 코드이다.
추천) ‘의존 객체 주입’을 사용해서 구현한 경우 - 유연하고 테스트 용이성을 높여준다
// 맞춤법 검사기 기능
public class SpellChecker {
// 맞춤법 검사를 할 때 필요한 자원 -> 사전(dictionary)
private final Lexicon dictionary;
// 인스턴스를 생성할 때 생성자에 필요한 자원(dictionary)을 넘겨주기
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}
맞춤법 검사기(SpellChcker)를 사용할 때, 의존 객체인 사전(dictionary)를 생성자의 파라미터로 주입해주면 된다.
References
- Effective Java(이펙티브 자바) - 조슈아 블로크, 인사이트 → [아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라.]