본문

스프링없이 의존성 주입하기

반응형

# DI(Dependecy Injection) - 의존성 주입


주입이란?

주입이란 말은 외부에서라는 뜻을 내포하고 있는 단어다.

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



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


Source 01) Tire.java

1
2
3
4
5
package expert001_02;
 
public interface Tire {
    String getBrand();
}
cs


Source 02) KoreaTire.java

1
2
3
4
5
6
7
8
9
package expert001_02;
 
public class KoreaTire implements Tire {
 
    @Override
    public String getBrand() {
        return "코리아 타이어";
    }
}
cs

Source 03) AmericaTire.java
1
2
3
4
5
6
7
8
9
10
11
package expert001_02;
 
public class AmericaTire implements Tire {
 
    @Override
    public String getBrand() {
        // TODO Auto-generated method stub
        return "미국 타이어";
    }
 
}
cs

Source 04) Car.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package expert001_02;
 
public class Car {
    Tire tire;
 
    public Car(Tire tire) {
        this.tire = tire;
    }
 
    public String getTireBrand() {
        return "장착된 타이어 : " + tire.getBrand();
    }
 
}
cs

Source 05) Driver.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package expert001_02;
 
public class Driver {
 
    public static void main(String[] args) {
        Tire tire = new KoreaTire();
        // Tire tire = new AmericaTire();
 
        Car car = new Car(tire);
 
        System.out.println(car.getTireBrand());
    }
 
}
cs

Result)

장착된 타이어 : 코리아 타이어



위의 코드를 현실세계에 비유하면 자동차가 생산될 때 어떤 타이어를 장착할까를 자동차가 스스로 고민하지 않고, 운전자가 차량을 생산할 때 운전자가 어떤 타이어를 장착할까를 고민하게 하는 것이다. 자동차는 어떤 타이어를 장착할까를 고민하지 않아도 된다.


의존성 주입을 적용할 경우 Car는 그저 Tire 인터페이스를 구현한 어떤 객체가 들어오기만 하면 정상적으로 작동하게 된다. 의존성 주입을 하면 확장성도 좋아지는데, 나중에 ChinaTire, JapanTire, EnglandTire 등등 어떤 새로운 타이어 브랜드가 생겨도 각 타이어 브랜드들이 Tire 인터페이스를 구현한다면 Car.java 코드를 변경할 필요없이 사용할 수 있기 때문이다(또한 다시 컴파일할 필요도 없다).


현실 세계에서는 인터페이스라는 말보다 표준화했다는 말이 더욱 와 닿을 것이다. 대표적인 표준화 사례는 페트병의 병마개다. 혹시 냉장고 안에 어러 회사의 음료수 페트병이 있다면 서로 뚜껑을 바꿔서 닫아보자. 페트병과 그 마개를 표준화된 규격에 맞춰 생산했기 떄문이다.


"현실 세계의 표준 규격 준수 = 프로그래밍 세계의 인터페이스 구현"




[**중요] [ 스프링 없이 의존성 주입하기 2 - 속성을 통한 의존성 주입 ]


생성자를 통해 의존성을 주입하는 것을 다시 현실 세계의 예로 들어 생각해 보면 자동차를 생산(구입)할 때 한번 타이어를 장착하면 더 이상 타이어를 교체 장착할 방법이 없다는 문제가 생긴다. 더 현실적인 방법은 운전자가 원할 때 Car의 Tire를 교체하는 것이다. 자바에서 이를 구현하려면 생성자가 아닌 속성을 통한 의존성 주입이 필요하다.


프로그래밍 세계에서는 생성자를 통해 의존성을 주입하는 방법과 속성을 통해 의존성을 주입하는 방법 중 어느 쪽이 더 좋은가에 대한 의견이 분분한데, 대부분의 프로젝트에서는 속성을 통한 의존성 주입을 선호하는 듯하다

특히 스프링에서 애노테이션(@)을 사용하는 경우 주로 속성 주입 방식을 사용하게 된다.



Source 01) Tire.java

1
2
3
4
5
package expert001_03;
 
public interface Tire {
    String getBrand();
}
cs

Source 02) KoreaTire.java

1
2
3
4
5
6
7
8
9
package expert001_03;
 
public class KoreaTire implements Tire {
 
    @Override
    public String getBrand() {
        return "코리아 타이어";
    }
}
cs

Source 03) AmericaTire.java

1
2
3
4
5
6
7
8
9
10
package expert001_03;
 
public class AmericaTire implements Tire {
 
    @Override
    public String getBrand() {
        return "미국 타이어";
    }
 
}
cs

Source 04) Car.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package expert001_03;
 
public class Car {
    Tire tire;
 
    // public Tire getTire() {
    //     return tire;
    // }
 
    public void setTire(Tire tire) {
        this.tire = tire;
    }
 
    public String getTireBrand() {
        return "장착된 타이어 : " + tire.getBrand();
    }
}
cs

Source 05) Driver.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package expert001_03;
 
public class Driver {
 
    public static void main(String[] args) {
        Tire tire = new KoreaTire();
        Car car = new Car();
        car.setTire(tire);
        
        System.out.println(car.getTireBrand());
        
    }
}
cs

Result)

장착된 타이어 : 코리아 타이어




- 출처 및 참고자료 : 스프링 입문을 위한 자바객체지향의 원리와 이해(김종민 저)

반응형

공유

댓글