리셋 되지 말자

스프링 없이 의존성 주입하기 1 - 생성자를 통한 의존성 주입 본문

Java(폐지)/spring 책

스프링 없이 의존성 주입하기 1 - 생성자를 통한 의존성 주입

kyeongjun-dev 2020. 8. 6. 14:40

의사 코드

  • 운전자가 타이어를 생산한다.
  • 운전자가 자동차를 생산하면서 타이어를 장착한다.

자바로 표현-생성자 사용

TIre tire = new KoreaTire();
Car car = new Car(tire);

주입이란 외부에서라는 뜻을 내포하는 단어다.
자동차 내부에서 타이어를 생산하는 것이 아니라 외부에서 생산된 타이어를 자동차에 장착하는 작업이 '주입'이다.

Tire에 대한 의존성을 해결한 경우

Car 객체가 Tire를 직접 생산하는, 즉 Tire에 대한 Car의 의존성을 자체적으로 해결한 방식

itre 객체를 Car 생성자의 인자로 주입(장착)

  • 시퀀스 다이어그램

  • 클래스 다이어그램

Car 생성자의 인자로 Tire가 들어감. 나머지는 동일

소스 코드

  • Tire.java
package expert001_02;

public interface Tire {
    public abstract String getBrand();
}
  • KoreaTire.java
package expert001_02;

public class KoreaTier implements Tire{
    public String getBrand() {
        return "코리아 타이어";
    }
}
  • AmericaTire.java
package expert001_02;

public class AmericaTIre implements Tire{
    public String getBrand() {
        return "아메리카 타이어";
    }
}
  • Car.java
package expert001_02;

public class Car {
    Tire tire;
    public Car(Tire tire) {
        this.tire = tire;
    }

    public String getTireBrand() {
        return "장착된 타이어: " + tire.getBrand();
    }
}
  • Driver.java (main)
package expert001_02;

public class Driver {
    public static void main(String[] args) {
        Tire tire = new KoreaTier();
        System.out.println(tire.getBrand());

        Car car = new Car(tire);
        System.out.println(car.getTireBrand());
    }
}
  • 실행 결과
코리아 타이어
장착된 타이어: 코리아 타이어

운전자가 차량을 생성할 때 어떤 타이어를 장착할지 정할 수 있다.

JUnit 테스트 코드

  • CarTest.java
package expert001_02;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class CarTest {

    @Test
    void 자동차_코리아타이어_장착_타이어브랜드_테스트() {
        Tire tire1 = new KoreaTier();
        Car car1 = new Car(tire1);

        assertEquals("장착된 타이어: 코리아 타이어", car1.getTireBrand());
    }

    @Test
    void 자동차_아메리카타이어_장착_타이어브랜드_테스트() {
        Tire tire2 = new AmericaTier();
        Car car2 = new Car(tire2);

        assertEquals("장착된 타이어: 아메리카 타이어", car2.getTireBrand());
    }

}
  • 결과

DI의 장점

이전의 Car.java의 Car 클래스에서는 Car 객체를 생성할 때, 어떤 타이어가 장착이 되는지 정확히 알아야만 했다. 하지만 수정 후에는 Car에 Tire 객체만 넣어주면 정상으로 동작한다.
확장성 면에서도 나중에 ChinaTire등 새로운 타이어가 만들어져도 Car 클래스를 뜯어고치지 않아도 된다.
Car.java, Tire.java를 하나의 모듈로 그리고 Driver.java, KoreaTire.java, AmericaTire.java를 각각 하나의 모듈로 만들면 나중에 새로운 ChinaTire.java가 생겨도 Driver.java와 ChinaTire.java만 컴파일해서 배포하면 된다.
더 많은 코드를 재배포할 필요가 없도록 구성해야만 코드 재컴파일과 재배포에 대한 부담을 덜 수 있다.(인터페이스 사용의 장점)

전략 패턴의 접목

  • 전략:Tire를 구현한 KoreaTire, AmericaTire
  • 컨텍스트:Car의 getTireBrand() 메서드
  • 클라이언트:Driver의 main() 메서드
Comments