객체지향 프로그래밍 패러다임에서는 소프트웨어가 높은 응집성과 낮은 결합성을 가져야 한다.
(* 응집성 : 하나의 모듈이 단일의 역할만을 할 경우 높은 응집성을 가진다. → 단일 책임원칙)
(* 결합성 : 모듈이 다른 모듈에 얼마나 의존하는지에 대한 척도)
결합성을 낮추기 위해서는 상위 수준 모듈이 하위 수준 모듈에 의존하지 않아야한다. 이를 의해서는 의존성 주입패턴을 사용하면 된다.
만약, A.js, B.js, C.js가 존재할때 각 파일들이 서로 얽혀있다면 결합성이 강해진다.
export.module = ()=>{
// this is A
}
const A = require("A.js")
export.module = () =>{
// this is B
}
const B = require("B.js")
export.module = () =>{
// this is C
}
이렇게 코드를 구성하게 되면 결합성이 강하기 때문에 모듈의 확장성을 제한하고, 단위 테스트 또한 어려워진다.
즉, stateful한 instance(=export한 특정 인스턴스)에 의존하기 때문에 문제가 발생한다. 따라서 stateful한 모듈(팩토리, 생성자, 인터페이스 등등)을 로드하게 되면 결합성을 낮출 수 있다.
주로 생성자를 이용하거나 메소드를 이용해서 의존성을 주입한다.
class Chef{
private Recipe recipe
public Chef(Recipe tmp){ // 생성자로 레시피를 받아서 입력한다.
this.recipe = tmp
}
public setRecipe(Recipe tmp){// setter메소드로 레시피를 입력해준다.
this.recipe = tmp
}
}
class Restaurant{
private Chef burgerChef = new Chef(new HamburgerRecipe())
private Chef spagettiChef = new Chef(new SpageettiRecipe())
public changeMenu(){
burgerChef = new Chef(new CheeseBurgerRecipe())
}
}
이렇게 의존성을 주입하는 경우 어떤 장점이 있는지 알아보자.