DI란 Dependency Injection의 줄임말로 , 다양한 우리 말 번역이 있지만, 이 글에서는 의존관계 주입이라는 말로 사용할 것.
“A가 B에 의존한다.”는 표현은 어떤 의미일까 ? 추상적인 표현이지만, 토비의 스프링에서는 다음과 같이 정의한다
의존 대상 B가 변하면, 그것이 A에 영향을 미친다. - 토비의 스프링 3.1
즉, B의 기능이 추가 또는 변경되거나 형식이 바뀌면 그 영향이 A에 미친다 .
다음은 햄버거 가게 요리사 예시를 보며 설명을 계속할 것.
햄버거 가게 요리사는 레시피에 의존한다. 버거 레시피가 변화하게 되었을 때(햄버거 레시피에서 야채버거 레시피로), 변화된 레시피에 따라서 요리사는 버거 만드는 방법을 수정해야 한다. 레시피의 변화가 요리사의 행위에 영향을 미쳤기 때문에 , **“요리사는 레시피에 의존한다”**고 말할 수 있다.
class BurgerChef {
private HamBurgerRecipe hamBurgerRecipe;
public BurgerChef() {
hamBurgerRecipe = new HamBurgerRecipe();
}
}
위 BurgerChef 예시를 보자. 지금의 구현에서는 HamBurgerRecipe만을 의존할 수 있는 구조로 되어있다. 더 다양한 BurgerRecipe를 의존 받을 수 있게 구현하려면 인터페이스로 추상화해야 한다.
class BurgerChef {
private BurgerRecipe burgerRecipe;
public BurgerChef() {
burgerRecipe = new HamBurgerRecipe();
//burgerRecipe = new CheeseBurgerRecipe();
//burgerRecipe = new ChickenBurgerRecipe();
}
}
interface BugerRecipe {
newBurger();
// 이외의 다양한 메소드
}
class HamBurgerRecipe implements BurgerRecipe {
public Burger newBurger() {
return new HamBerger();
}
// ...
}
의존관계를 인터페이스로 추상화하게 되면, 더 다양한 의존 관계를 맺을 수가 있고, 실제 구현 클래스와의 관계가 느슨해지고, 결합도가 낮아진다.
의존관계가 무엇인지에 대해, 그리고 다양한 의존관계를 위해 인터페이스로 추상화함을 알아봤다. 그렇다면, Dependency Injection은 무엇인가?
지금까지의 구현에서는 BurgerChef 내부적으로 의존관계인 BurgerRecipe가 어떤 값을 가질지 직접 정하고 있다. 만약 어떤 BurgerRecipe를 만들지를 버거 가게 사장님이 정하는 상황을 상상해보자. 즉, BurgerChef가 의존하고 있는 BurgerRecipe를 외부(사장님)에서 결정하고 주입하는 것이다.
이처럼 그 의존관계를 외부에서 결정하고 주입하는 것이 DI(의존관계 주입)이다.