DI 의존성 주입에 대해 알아보는 시간
일반적으로 의존관계는 상위 계층이 하위 계층에 의존하는 형태입니다.
class A {
constuctor() {
this.obj = new B(1);
}
}
class B {
constructor(value: number) {
this.value = value;
}
}
위 코드는 상위 계층 A가 B에 의존하고 있습니다. 결합도가 높기 때문에 재활용 측면에서 좋지 않습니다. 이 때 B에 의해 생성된 객채를 외부에서 주입하면 A가 B에 의존하는 관계를 부수며 결합도를 낮출 수 있습니다.
class A {
constructor(public value: B) {
this.value = value;
}
}
class B {
constructor(public value: number) {
this.value = value;
}
}
new A(new B(1));
B에 의해 생성된 객체가 A로 주입됩니다.
하지만 A가 한가지 B에 의존하고 있는 부분이 있습니다. 바로 constructor에 입력되는 value의 타입입니다. 타입이 특정 클래스에 의존하고 있기 때문에 의존관계 역전 원칙에 위배됩니다.
의존성 분리: 위 계층이 하위 계층의 구현으로부터 독립되게 할 수 있다.
첫째, 상위 모듈은 하위 모듈에 의존해서는 안된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.
둘째, 추상화는 세부 사항에 의존해서는 안된다. 세부사항이 추상화에 의존해야 한다.
주입으로 인해 호출 구조에 대한 의존성은 분리되었지만, 추가로 나머지 의존성을 완전히 분리시켜야합니다. 타입과 관련해서는 interface를 이용할 수 있습니다.
interface IndependentInt {
value: number;
}
class A {
constructor(public value: IndependentInt) {
this.value = value;
}
}
class B {
constructor(public value: IndependentInt['value']) {
this.value = value;
}
}
new A(new B(1));
이로써 A는 B로 부터 완전히 독립되었습니다.
우리가 알고있는 SOLID의 D는 의존관계 역전 원칙 (Dependency inversion principle)를 의미합니다. 위에서 본 것 처럼 일반작으로 상위 계층이 하위 계층에 의존하나 의존관계를 역전시켜 상위 계층이 하위 계층으로부터 완전히 독립된 환경을 구현하기 위함입니다. 이 법칙은 크게 두 가지를 지켜야합니다.
첫째, 상위 모듈은 하위 모듈에 의존해서는 안된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.
둘째, 추상화는 세부 사항에 의존해서는 안된다. 세부사항이 추상화에 의존해야 한다.
의존성 주입은 이 의존관계 역전 원칙을 지키는 수단중 하나입니다.