모든지 기록하자!

DI란 무엇인가 본문

Spring

DI란 무엇인가

홍크 2021. 11. 11. 02:24
728x90

DI는 Dependency Injection의 줄임말로 의존관계 주입이라고 한다.

 

Dependency 의존 관계란?

"A가 B를 의존한다."는 말은 의존 대상 B가 변하면 그것이 A에 영향을 미친다는 것이다.

 

아래 예시를 살펴보자

 

피자 가게 요리사는 피자 레시피에 의존한다. 피자 레시피가 변화하게 되었을 때

변화된 레시피에 따라서 요리사는 피자 만드는 방법을 수정해야 한다. 

레시피의 변화가 요리사의 행위에 영향을 미쳤기 때문에 요리사는 레시피에 의존한다고 말할 수 있다.

 

class PizzaChef {
    private PizzaChefRecipe pizzaChefRecipe;

    public PizzaChef() {
        pizzaChefRecipe = new PizzaChefRecipe();        
    }
}

 

의존관계를 인터페이스로 추상화

PizzaChef 예시를 보면 PizzaChefRecipe만을 의존할 수 있는 구조로 되어있다.

다양한 PizzaRecipe를 의존받을 수 있게 구현하려면 인터페이스로 추상화해야 한다.

class PizzaChef {
    private PizzaRecipe pizzaRecipe;

    public PizzaChef() {
        pizzaRecipe = new PizzaRecipe();
        //pizzaRecipe = new CheesePizzaRecipe();
        //pizzaRecipe = new BulgogiPizzaRecipe();
    }
}

interface PizzaRecipe {
    newPizza();
    // 이외의 다양한 메소드
} 

class PizzaRecipe implements PizzaRecipe {
    public Pizza newPizza() {
        return new Pizza();
    }
    // ...
}

의존관계가 무엇인지에 대해, 그리고 다양한 의존관계를 위해 인터페이스로 추상화를 알아봤다.

그렇다면 Dependency Injection은 무엇인가?

 

지금까지의 구현에서는 PizzaChef 내부적으로 의존 관계인 PizzaRecipe가 어떤 값을 가질지 직접 정하고 있다. 만약 어떤 PizzaRecipe를 만들지를 피자 가게 사장님이 정하는 상황을 상상해보자. 즉, PizzaChef가 의존하고 있는 PizzaRecipe를 외부(사장님)에서 결정하고 주입하는 것이다.

이처럼 그 의존관계를 외부에서 결정하고 주입하는 것이 DI(의존관계 주입)이다.

DI 구현 방법

DI는 의존관계를 외부에서 결정하는 것이기 때문에, 클래스 변수를 결정하는 방법들이 곧 DI를 구현하는 방법이다.

런타임 시점의 의존관계를 외부에서 주입하여 DI 구현이 완성된다.

 

Pizza 가게 주인이 어떤 레시피를 주입하는지 결정하는 예시로 설명해보자

 

-생성자 이용

class PizzaChef {
    private PizzaRecipe pizzaRecipe;

    public PizzaChef(PizzaRecipe pizzaRecipe) {
        this.pizzaRecipe = pizzaRecipe;
    }
}

class PizzaRestaurantOwner {
    private PizzaChef pizzaChef = new PizzaChef(new PizzaRecipe());

    public void changeMenu() {
        PizzaChef = new PizzaChef(new CheesePizzaRecipe());
    }
}

-Setter 메소드 이용

class PizzaChef {
    private PizzaRecipe pizzaRecipe = new PizzaRecipe();

    public void setPizzaRecipe(PizzaRecipe pizzaRecipe) {
        this.pizzaRecipe = pizzaRecipe;
    }
}

class PizzaRestaurantOwner {
    private PizzaChef pizzaChef = new PizzaChef();

    public void changeMenu() {
        pizzaChef.setPizzaRecipe(new CheesePizzaRecipe());
    }
}

 

DI 장점

1. 의존성이 줄어든다.

의존한다는 것은 그 의존 대상의 변화에 취약하는 것이다. DI로 구현하게 되었을 때, 주입받는 대상이 변하더라도

그 구현 자체를 수정할 일이 없거나 줄어들게 된다.

 

2. 재사용성이 높은 코드가 된다.

기존에 PizzaChef 내부에서만 사용되었던 PizzaRecipe를 별도로 구분하여 구현하면 다른 클래스에서 재사용할 수가 있다.

 

3. 테스트하기 좋은 코드가 된다.

PizzaRecipe의 테스트를 PizzaChef 테스트와 분리하여 진행할 수 있다.

 

4. 가독성이 높아진다.

PizzaRecipe의 기능들을 별도로 분리하게 되어 가독성이 높아진다.

 

 

참고 - https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/

728x90

'Spring' 카테고리의 다른 글

[Spring] Spring 과 Spring Boot 의 차이점은?  (0) 2022.01.01
AOP란 무엇인가  (0) 2021.11.11
[스프링, JSP] 모달창 리스트에 적용시키기  (0) 2021.09.02
Spring Annotation  (0) 2021.07.12
Comments