728x90
[ 자원은 직접 명시하지 말고 의존객체 주입을 사용하라 ]
많은 클래스는 하나 이상의 자원에 의존함
이런 클래스 싱글톤과 정적 유틸리티 클래스로 정의하면 적절하지 못한데, 그의 이유는 다음과 같음
1. 싱글톤 예시 코드
public class SpellChecker1 {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker1 INSTANCE = new SpellChecker1();
// 객체 생성 방지
private SpellChecker1() {
}
public boolean isValid(String word) {
return false;
}
public List<String> suggestions(String type){
return null;
}
public static void main(String[] args) {
SpellChecker1 spellChecker1 = SpellChecker1.INSTANCE;
spellChecker1.isValid("test");
}
}
2. 정적 유틸리티 클래스 예시 코드
public class SpellChecker2 {
private static final Lexicon dictionary = new Lexicon();
// 객체 생성 방지
private SpellChecker2() {
throw new AssertionError();
}
public static boolean isValid(String word) {
return false;
}
public static List<String> suggestions(String type){
return null;
}
}
위 두가지의 방법이 적합하지 않은 이유는,
- 사전(Lexicon)은 언어별로 존재할 수 있고 특수한 용도의 어휘용 사전이 별도로 필요할 수 있음
- 단순히 사전 클래스 한가지만으로는 모든 단어를 대응할 수는 없음
위와 같은 이유로 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않을 수 있음.
그렇다면 어떤 방식으로 작성해야 하나?
A. 의존 객체 주입 패턴
public class SpellChecker3 {
private final Lexicon dictionary;
// 생성자를 이용해서 의존성 주입 수행
public SpellChecker3(Lexicon dictionary) {
this.dictionary = dictionary;
}
...
public boolean isValid(String word) {
System.out.println("call is Valid");
return false;
}
public List<String> suggestions(String type){
System.out.println("call suggestions");
return null;
}
...
}
class KoreaDictionary extends Lexicon{}
Lexicon koreaLexicon = new KoreaDictionary();
SpellChecker3 sc1 = new SpellChecker3(koreaLexicon);
의존 객체 주입 패턴은 인스턴스를 생성할때 생성자에 필요한 자원을 넘겨주는 방식을 의미하며,
위와 같이 맞춤법 검사기 인스턴스를 생성할때 생성자로 필요한 Lexicon 인스턴스를 전달하여 주입할 수 있음
<결론>
클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 줌
-> 싱글톤과 정적 유틸리티 클래스는 적합하지 않음.
& 이 자원들을 클래스가 직접 만들게 해서도 안됨.
===> 대신, 필요한 지원을 (혹은 그 자원을 만들어주는 팩토리를) 생성자(또는 정적 팩토리나 빌더)에 넘겨줌
이런 의존 객체 주입 기법은 클래스의 유연성, 재사용성, 테스트 용이성을 개선
728x90
반응형