의존 객체 주입의 사용 이유
- Coding/Java
- 2020. 11. 6.
하나의 클래스를 여러 용도로의 사용
많은 클래스가 하나의 자원에 의존한다. 이렇게 여러 클래스에게 의존받는 자원은 여러 용도로 사용이 된다. 예를 들어, 사전이라는 SpellChecked 클래스가 있다. 이 클래스가 여러 사전을 사용할 수 있도록 만들어보자.
1) 정적 유틸리티의 잘못된 사용
public class SpellChecker {
private static final Lexicon dictionary = ...;
// 인스턴스 생성 막기 (post: https://seohae.github.io/2020/07/24/java/25_InstancePrivateUse/)
private SpellChecker() {}
}
2) 싱글턴의 잘못된 사용
public class SpellChecker {
private final Lexicon dictionary = ...;
private SpellChecker(...) {
...
}
public static SpellChecker INSTANCE = new SpellChecker(...);
}
위 두개의 정적 유틸리티와 싱글턴은 잘못 사용된 예시이다. 위 두개의 예제는 유연하지 않고 테스트하기에도 어렵다. 만약 dictionary 필드 하나를 모든 용도로 사용하려고 한다면 이는 애매한 상황으로 올 수 있다. 사전에는 여러 가지의 사전이 존재하는데 과연 dictionary 필드 하나로 우리가 원하는 서비스를 구현할 수 있을지 의심해봐야한다.
의존 객체 주입의 사용
위 예제를 다시 살펴보자.
1) 정적 유틸리티의 잘못된 사용
public class SpellChecker {
private static final Lexicon dictionary = ...;
// 인스턴스 생성 막기 (post: https://seohae.github.io/2020/07/24/java/25_InstancePrivateUse/)
private SpellChecker() {}
}
간단히 dictionary 필드에서 final 한정자를 제거하고 dictionary 필드의 값을 변경하는 메소드를 추가할 수는 있다. 하지만 이 방시은 오류를 내기 쉽고 멀티스레드 환경에서는 쓸 수 없는 단점을 가지게된다. 사용하는 자원에 따라 동작이 달라지는 클래스에서는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.
클래스가 여러 자원 인스턴스를 지원해야 하며, 클라이언트가 원하는 자원을 사용해야한다.
이 조건을 만족하는 간단한 패턴이 존재하는데, 이것이 바로 의존 객체 주입이다. 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식으로, 이는 의존 객체 주입의 한 형태이다.
- 의존 객체 주입의 사용
public class spellChecker {
private final Lexion dctionary;
// 의존 객체 주입
public SpellChecker(Lexion dictionary) {
this.dictionary = Objects.requiredNonNull(dictionary);
}
}
dictionary 필드(1개의 자원)만 사용하지만, 자원이 몇개든 의존 관계가 어떻든 이제 상관이 없어졌다. 또한 final 한정자를 사용하여 불변을 보장할 수 있고, 같은 자원을 사용하려는 여러 클라이언트가 해당 객체를 안심하고 공유할 수 있게되었다. 의존 객체 주입은 생성자, 정적팩터리, 빌더 등에 모두 적용이 가능하다.
의존 객체 주입의 팩토리 메소드 패턴
팩토리 메소드 패턴(Factory Method Pattern) : 이 패턴의 변형으로 사용하는 생성자에 자원 팩터리를 넘겨주는 방식이 있다.
여기서 팩터리란, 호출할때마다 특정 타입의 인스턴스를 반복해서 만들어주는 객체이다. 의존 객체 주입이 유연성과 테스트 용이성을 개선해주긴 하지만, 의존성이 수천개나 되는 큰 프로젝트 에서는 코드를 어지럽게 만들 수 있다. 우리가 많이 사용하는 스프링 프레임워크에서의 의존 객체 주입은 이러한 단점을 해소시켜 준다. 의존 객체 주입이라 하는 이 기법은 클래스의 유연성, 재사용성, 테스트 용이성을 개선시켜준다. 팩토리 메소드 패턴을 사용함으로써 클래스간의 결합도를 낮춰주고, 직접 객체를 생성하여 사용하는 것을 막아주는 효과가 있다.
'Coding > Java' 카테고리의 다른 글
java8에서의 날짜/시간 API (LcalDate/LocalTime) (0) | 2020.11.06 |
---|---|
자바8의 default 메서드 등장 (0) | 2020.11.06 |
제네릭 메서드 (0) | 2020.11.06 |
숫자형 스트림 (0) | 2020.11.06 |
싱글턴 패턴 (0) | 2020.11.06 |