Java/Effective Java
[아이템 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
setung
2021. 12. 20. 15:46
SpellChecker라는 맞춤법을 검사하는 클래스가 있다. 이 클래스는 Lexicon이란 사전 클래스를 의존한다.
코드는 아래와 같다.
class SpellChecker {
private static final Lexicon dictionary = new KoreanDictionary();
public static boolean isValid(String word) {
return true;
}
public static List<String> suggestions(String typo) {
return new ArrayList<>();
}
}
class KoreanDictionary implements Lexicon {
}
interface Lexicon {
}
코드에선 KoreanDictionary를 직접 생성해서 사용하고 있는데, 다른 사전으로 교체할 수 없다는 문제점이 있다. EnglishDictionary가 필요하다면 별도의 SpellChecker 클래스를 만들어야 한다.
그럼 Lexicon에 final 키워드를 빼고 setter 메서드를 통해 사전을 교체하도록 만들면 어떨까?
class SpellChecker {
private static Lexicon dictionary;
public static void setDictionary(Lexicon dictionary) {
SpellChecker.dictionary = dictionary;
}
public static boolean isValid(String word) {
return true;
}
public static List<String> suggestions(String typo) {
return new ArrayList<>();
}
}
이 방식은 멀티스레드 환경에서 사용할 수 없다.
책에서 설명하는 가장 좋은 방법은 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식이다.
class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public boolean isValid(String word) {
return true;
}
public List<String> suggestions(String typo) {
return new ArrayList<>();
}
}
public class Main {
SpellChecker korSpellChecker = new SpellChecker(new KoreanDictionary());
SpellChecker engSpellChecker = new SpellChecker(new EnglishDictionary());
}
의존 객체 주입 방식을 통해 클래스의 유연성, 재사용성, 테스트 용이성에 이점을 준다.
참고로 의존하는 객체수에 비례하여 코드가 복잡해질 수 있는데, Spring의 핵심 기술인 IOC/DI가 의존 객체 주입을 좀 더 편하게 사용하도록 지원을 해준다.