아이템 5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
많은 클래스가 하나 이상의 자원에 의존합니다.
아래 SpecllChecker는 사전(dictionary)에 의존하고 있는데, 아래처럼 구현하는 경우를 많이 볼 수 있습니다.
정적 유틸리티
public class SpellChecker {
private static final Lexicon dictionary = new LexiconDictionary();
private static boolean isValid(String word) { ... }
private SpeckChecker() { } // 객체 생성 방지
}
싱글턴
public class SpellChecker {
private final Lexicon dictionary = new LexiconDictionary();
public static SpellChecker INSTANCE = new SpellChecker(...);
private SpellChecker(...) { }
public boolean isValid(String word) { ... }
}
위와 같은 경우 사전(dictionary)이 하나로 고정이 되기 때문에 좋은 방법이 아닙니다.
SpellChecker가 여러 종류의 사전을 사용할 수 있도록 하려면 final을 제거하고 dictionary를 변경하는 메서드를 추가할 수 있지만, 오류를 내기 쉬우며 멀티스레드 환경에서는 쓸 수 없습니다.
대신 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주도록 하면 됩니다.
의존 객체 주입
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) { ... }
}
- 자원이 몇 개든 의존 관계가 어떻든 상관없이 작동합니다.
- 불변을 보장하여 여러 클라이언트가 의존 객체들을 안심하고 공유할 수 있습니다.
의존 객체 주입은 유연성과 재사용성, 테스트 용이성을 개선해주기는 하지만, 의존성이 많아질 수록 코드가 어지러워집니다.
다행히 스프링과 같은 의존 객체 주입 프레임워크에서 이를 해소해주고 있습니다.
Reference
반응형
'☕️ JAVA > Effective JAVA' 카테고리의 다른 글
[Effective Java] 아이템 32 : 제네릭과 가변인수를 함께 쓸 때는 신중하라 (0) | 2022.01.06 |
---|---|
[Effective Java] 아이템 21 : 인터페이스는 구현하는 쪽을 생각해 설계하라 (0) | 2022.01.02 |
[Effective Java] 아이템 68 : 일반적으로 통용되는 명명 규칙을 따르라 (0) | 2021.12.18 |
[Effective Java] 아이템 49 : 매개변수가 유효한지 검사하라 (0) | 2021.12.04 |
[Effective Java] 아이템 33 : 타입 안전 이종 컨테이너를 고려하라 (0) | 2021.11.28 |