개인공부/language

[JAVA] Effective JAVA - Item 5 : Prefer dependency injection to hardwiring resources

파뱁 2025. 4. 7. 14:40
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
반응형