많은 클래스가 하나 이상의 자원에 의존한다.
다음과 같은 맞춤법 검사기 클래스(SpellChecker)는 Dictionary 클래스에 의존한다.
public class SpellChecker {
private static final Dictionary dictionary = new DefaultDictionary();
private SpellChecker() {
}
public static boolean isValid(String word) {
...
}
public static List<String> suggestions(String typo) {
...
}
}
public class SpellChecker {
private final Dictionary dictionary = new DefaultDictionary();
private SpellChecker() {}
public static final SpellChecker INSTANCE = new SpellChecker();
public boolean isValid(String word) {
...
}
public List<String> suggestions(String typo)
...
}
}
SpellChecker 클래스가 다양한 사전을 사용할 수 있도록 변경하려면 어떻게 할까?
인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식이다.
스프링을 사용해 봤다면 익숙한 방식일 것이다.
의존 객체 주입은 생성자, 정적 팩토리, 빌더 모두에 똑같이 응용할 수 있다.
public interface Dictionary {
boolean isValid(String word);
List<String> suggestions(String typo);
}
public class SpellChecker {
private final Dictionary dictionary;
public SpellChecker(Dictionary dictionary) {
this.dictionary = dictionary;
}
public boolean isValid(String word) {
return dictionary.isValid();
}
public List<String> suggestions(String typo) {
return dictionary.suggestions();
}
}
SpellChecker english = new SpellChecker(new EnglishDictionanry());
SpellChecker korean = new SpellChecker(new KoreanDictionary());
english.isValid("test");
korean.isValid("테스트");
팩토리 메소드 패턴을 구현하여 생성자에 팩토리 클래스를 넘겨주는 방식이 있다.
Dictionary를 리턴해 주는 DictionaryFactory 클래스
public interface DictionaryFactory {
Dictionary getDictionary();
}
public class EnglishDictionaryFactory implements DictionaryFactory {
@Override
public Dictionary getDictionary() {
return new EnglishDictionary();
}
}
public class KoreanDictionaryFactory implements DictionaryFactory {
@Override
public Dictionary getDictionary() {
return new KoreanDictionary();
}
}
public class SpellChecker {
private final Dictionary dictionary;
public SpellChecker(DictionaryFactory dictionaryFactory) {
this.dictionary = dictionaryFactory.getDictionary();
}
public boolean isValid(String word) {
return dictionary.isValid();
}
public List<String> suggestions(String typo) {
return dictionary.suggestions();
}
}
DictionaryFactory dictionaryFactory = new KoreanDictionaryFactory();
SpellChecker spellChecker = new SpellChecker(dictionaryFactory);
spellChecker.isValid("테스트");
public class KoreanDictionaryFactory implements DictionaryFactory {
@Override
public Dictionary getDictionary() {
return new KoreanDictionaryV2();
}
}