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가 의존 객체 주입을 좀 더 편하게 사용하도록 지원을 해준다.
'Java > Effective Java' 카테고리의 다른 글
[아이템 7] 다 쓴 객체 참조를 해제하라 (0) | 2021.12.23 |
---|---|
[아이템 6] 불필요한 객체 생성을 피하라 (0) | 2021.12.21 |
[아이템 4] 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2021.09.30 |
[아이템 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2021.09.30 |
[아이템 2] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2021.09.28 |
댓글