DI(Dependency Injection)

Sixhustle·2021년 12월 12일
0

Spring

목록 보기
4/10
post-custom-banner

Dependency

의존성이란 ?

  1. class 간의 연결정도
  2. A 파일이 변경될 때, B 파일도 변경되는 경우
class BurgerChef {
    private HamBurgerRecipe hamBurgerRecipe;

    public BurgerChef() {
        hamBurgerRecipe = new HamBurgerRecipe();        
    }
}

위와 같이 BurgerChef class를 실행할 때, HamBurgerRecipe class가 필요한 경우를
BurgerChef class가 HamBurgerRecipe에 의존성을 가지고 있다.(의존하고 있다.) 라고 합니다.

강한 의존성을 가질 경우,

  1. 변경에 유연하지 못하고
  2. 재사용성이 낮아지고
  3. 테스트 코드 작성이 어려워진다

의존성을 낮추기 위해서 아래와 같이 의존 관계를 interface로 추상화할 수 있다.

class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef() {
        burgerRecipe = new HamBurgerRecipe();
        //burgerRecipe = new CheeseBurgerRecipe();
        //burgerRecipe = new ChickenBurgerRecipe();
    }
}

interface BugerRecipe {
    newBurger();
} 

class HamBurgerRecipe implements BurgerRecipe {
    public Burger newBurger() {
        return new HamBerger();
    }
    // ...
}

의존 관계를 interface로 추상화 할 경우, HamBurgerRecipe, CheesBurgerRecipe, ChickenBurgerRecipe 등 다양한 의존 관계를 맺을 수 있고, 실제 구현 클래스와의 결합도가 낮아진다.


Dependency Injection

// 제3자(Boss)가 BurgerChef에게 CheeseBurgerRecipe(Dependency)를 Injection함
public class Boss {
   private final BurgerChef chef = new BurgerChef(new CheeseBurgerRecipe);
}   

제3자(다른 class)가 BurgerChef에게 어떤 BurgerRecipe를 사용할 것인지 정하는 것이다.

아래 3가지 조건을 충족하면 Dependency Injection이라 말한다.

  1. class모델이나 코드에는 runtime 시점의 의존관계가 드러나지 않는다.
  2. runtime시점의 의존관계는 container나 factory 등 제3의 존재가 결정한다.
  3. 의존관계는 사용할 object에 대한 레퍼런스를 외부에서 주입해줌으로써 만들어진다.

구현 방법

1. Constructor Injection(생성자 주입) : 가장 권장

@Service
public class BurgerChef {
   private BurgerRecipe recipe;
   
   @Autowired
   public Service(BurgerRecipe recipe) {
      this.recipe = recipe;
   }
}

//   DI
public class Boss {
   private final BurgerChef chef = new BurgerChef(new CheeseBurgerRecipe);
}

권장 이유

  1. 필수적으로 사용해야하는 의존성 없이는 class의 instance를 만들지 못하도록 강제할 수 있다.
  2. 생성자 parameter가 많아지면, 하나의 class가 많은 책임을 떠안는걸 알 수 있다.
  3. compile단계에서 순환 의존성을 알 수 있다. (field injection은 불가)
  4. final 키워드를 사용할 수 있어 객체가 불변하도록 할 수 있다. 제3 class에서 누군가 구현체 변경 불가

2. Setter Injection(수정자 주입)

단점

  1. 객체 생성 시 의존관계를 주입하지 않아도 객체 생성이 가능합니다.
  2. 따라서 NullPointerException이 발생할 수 있어 null check 로직이 추가로 필요합니다.

3. Field Injection

사용하지 말것!


장점

  1. 의존성이 줄어든다.

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

  3. 테스트 하기 좋음

  4. 가독성이 좋아진다.


References

post-custom-banner

0개의 댓글