•
사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.
◦
사전(dictionary)을 사용하는 맞춤법 검사 클래스가 있다고 생각해보자.
public class SpellChecker {
private static final Lexicon dictionary = ...;
private SpellChecker() {}
...
}
Java
복사
◦
위 코드의 사전인 Lexicon은 외부 클래스로, 만약 맞춤범 검사 클래스가 다른 언어를 지원한다하면 사전의 종류도 바뀌어야 한다.
public class SpellChecker {
private final Lexicon dictionary = ...;
private SpellChecker() {}
public static SpellChecker INSTANCE = new SpellChekcer();
...
}
Java
복사
◦
혹은 이처럼 싱글턴으로 구현될 수도 있다.
◦
이렇게 사용하는 동작에 따라 자원이 달라져야 하는 클래스에는 위와 같은 정적 유틸리티 방식이나 싱글턴 방식은 유연하지 않고 테스트하기 어려워 사용하기에 적합하지 않다.
•
이런 상황에서는 인스턴스를 생성할 때, 생성자에 필요한 자원은 넘겨주는 방식인 의존 객체 주입을 사용하면 된다.
public class SpellChecker {
private final Lexicon dictionary;
public SpellChekcer(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
...
}
Java
복사
•
위의 예시에서는 1개의 자원만 사용했지만, 의존 객체 주입 패턴은 의존 관계가 몇 개이든 상관없이 적용할 수 있다.
•
또한 불변을 보장하여 여러 클라이언트가 의존 객체를 안심하고 공유할 수 있고, 생성자, 정적 팩터리, 빌더 모두 동일하게 적용할 수 있다.
•
의존 객체 주입 패턴의 변형으로 생성자에 자원 팩터리를 넘겨주는 방식이 있다.
•
함수형 인터페이스를 통해 팩터리 메서드를 받아, 해당 자원을 사용할 때마다 팩터리에서 해당 자원의 인스턴스를 반복해서 생성해 사용할 수 있게 된다.
Mosaic create(Supplier<? extends Tile> tileFactory) {...}
Java
복사
•
의존 객체 주입 패턴은 유연성과 테스트 용이성을 개선해주지만, 의존성이 너무 많아지면 코드를 어지럽게 만들기도 한다.
•
의존 객체 주입을 사용하는 여러 프레임워크를 사용하여 이런 복잡한 코드를 개선할 수 있다.