의존관계는 객체 혼자 모든 일을 처리하기 힘들기 때문에 작업의 일부분을 다른 객체에게 위임하면서 발생한다.
즉, 특정 객체가 가진 책임과 역할을 다른 객체에게 위임하는 순간 발생한다.
-> Service 단에서 Dao를 통해 데이터베이스에 접근(데이터베이스 접근 로직을 위임 => 의존관계를 가짐)
import java.util.Calendar;
public class DateMessageProvider {
public String getDateMessage() {
Calendar now = Calendar.getInstance();
int hour = now.get(Calendar.HOUR_OF_DAY);
if(hour < 12) {
return "오전";
}
return "오후";
}
}
위의 클래스를 테스트 클래스에서 오전과 오후를 확인해보면, 두 개의 메소드 중에서 하나는 무조건 실패한다.
-> 이유는 위의 클래스가 Calendar와 의존관계를 가지기 때문이다.
테스트를 모두 성공하려면 Calendar을 통해 조회하는 컴퓨터 시간을 변경할 수 있어야 한다.
->but 현재 코드는 소스코드를 컴파일하는 시점에 Calendar 인스턴스가 결정되어 버린다.(강한결합)
Calender에서 반환되는 시간을 변경할 수 있도록 리팩토링해야한다.
-> Calendar 인스턴스의 생성을 클래스 내부에서 결정하는 것이 아니라, 클래스 외부에서 Calendar 인스턴스를 생성한 후 전달하는 구조로 바꿔야 한다.
import java.util.Calendar;
public class DateMessageProvider {
public String getDateMessage(Calendar now) { //메소드 인자로 전달
int hour = now.get(Calendar.HOUR_OF_DAY);
if(hour < 12) {
return "오전";
}
return "오후";
}
}
이 처럼 객체 간의 의존관계에 대한 결정권을, 의존관계를 가지는 객체가 아닌 외부의 누군가가 담당하도록 함으로써 좀 더 유연한 구조로 개발하는 것을 DI라고 한다.
문제점
싱글톤 패턴을 사용할 경우 싱글톤 패턴으로 구현된 클래스와 의존관계를 가지는 경우 해당 클래스와 강한 의존관계를 가지므로 생성자를 private으로 구현하여 상속할 수 없다.
-> 그러면 어떻게 싱글톤을 사용하지 않고 인스턴스를 하나만 유지할 수 있을까?