1. DI

  1. DI란?

    1. Dependency Injection의 줄임말로 의존관계 주입이라는 의미임
  2. Dependency(의존관계)?

    1. **“A가 B를 의존한다”**는 표현은 추상적인 표현이지만 결국은 의존 대상이 기능 추가 또는 변경이 일어나면 함께 영향을 미친다는 의미를 가짐

    2. [예제]

      // DI
      class BaseBall {
      	private Pitcher pitcher; // 투수
      
      	// 야구공
      	public BaseBall() {
      		pitcher = new Pitcher();
      	}
      }
      
      // 의존관계
      // 야구공은 투수와 의존함을 보여줌!
      // 야구공 - 투수
      // 야구공 - 포수
      // 야구공 - 타자
      // 야구공 - 심판
      
  3. 인터페이스로 추상화

    1. BaseBall로 예시로 들면, 구현에서 Pitcher만을 의존할 수 있는 구조로 되어 있으며, 더 다양한 메서드를 의존 받을 수 있게 구현하는 것인터페이스로 추상화 한다고 말함

    2. [예제]

      // 인터페이스로 추상화
      class BaseBall {
      	private Pitcher pitcher; // 투수
      	private Hitter hitter; // 타자
      
      	// 야구공[투수, 타자](생성자)
      	public BaseBall() {
      		pitcher = new Pitcher();
      		hitter = new Hitter();
      	}
      }
      
      // 인터페이스
      interface Hitter {
      	baseBallHit();
      	// 다양한 메서드
      }
      
  4. 구현방법

    1. 생성자를 이용함

      1. [예제]

        class BurgerChef {
            private BurgerRecipe burgerRecipe;
        
            public BurgerChef(BurgerRecipe burgerRecipe) {
                this.burgerRecipe = burgerRecipe;
            }
        }
        
        class BurgerRestaurantOwner {
            private BurgerChef burgerChef = new BurgerChef(new HamburgerRecipe());
        
            public void changeMenu() {
                burgerChef = new BurgerChef(new CheeseBurgerRecipe());
            }
        }
        
    2. 메서드를 이용함

      1. [예제]

        class BurgerChef {
            private BurgerRecipe burgerRecipe = new HamburgerRecipe();
        
            public void setBurgerRecipe(BurgerRecipe burgerRecipe) {
                this.burgerRecipe = burgerRecipe;
            }
        }
        
        class BurgerRestaurantOwner {
            private BurgerChef burgerChef = new BurgerChef();
        
            public void changeMenu() {
                burgerChef.setBurgerRecipe(new CheeseBurgerRecipe());
            }
        }
        
  5. 장점

    1. 의존성이 줄어듬
      1. 의존한다는 것은 그 의존대상의 변화에 취약하며, DI로 구현하게 되었을 때, 주입받는 대상이 변하더라도 그 구현 자체를 수정할 일이 없거나 줄어들게 됨
    2. 재사용성이 높은 코드가 됨
      1. BurgerChef 내부에서만 사용하던 것을 BurgerRecipe를 별도로 구분하여 구현해 다른 클래스에서도 재사용이 가능하도록 함
    3. 테스트하기 좋은 코드가 됨
      1. 각 테스트를 할 것을 분리하여 진행함
    4. 가독성이 높아짐
      1. 기능을 별도로 분리하여 가동성을 높임