현재 작성된 코드는 주문서비스 구현체(OrderServiceImpl)가 할인 정책 구현체를 선택하고 있는 상태이다. (FixDiscountPolicy / RateDiscountPolicy)
이를 공연에 대입해보자.
공연은 각 배역이 있고 그에 맞는 배우가 있다.
이를 매칭시켜보면
- 공연 = 애플리케이션(비지니스 로직 전체)
- 배역 = 인터페이스 (OrderService, DiscountPolicy)
- 배우 = 구현체 (OrderService, FixDiscountPolicy / RateDiscountPolicy)
배우가 상대 배역의 배우를 선택하고 있는 것과 똑같은 상황이라 할 수 있다. 즉, 배우가 공연도 해야하고 상대 배역까지 정해야하는 다양한 책임을 가지고 있음.
즉, 우리에게는 공연 기획자같은 역할에 맞는 배우를 지정하고 섭외하는 책임을 가진 담당자가 필요하다.
AppConfig
애플리케이션의 전체 동작 방식을 구성하기 위해 구현 객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스를 만들어보자.
위에서 언급한 것 이외에도 구현체가 인터페이스와 다른 구현체를 동시에 의존하는 것들을 모두다 AppConfig에서 설정하도록 바꿔야함.
- 다른 곳에서 AppConfig를 통하여 memberService를 호출하면 구현체인 MemberServiceImpl이 생성됨.
- 그 때 생성자를 통하여 MemoryMemberRepository(구현체)가 주입된다.
- 따라서 MemberServiceImpl은 오로지 인터페이스에만 의존하게 되는 것이다.
- MemberServiceImpl은 저장소에 대해서는 알지 못하고 외부에서 주입해주는 형식 = 생성자 주입
- MemberServiceImpl은 "의존관계에 대한 고민"은 외부(AppConfig)에 맡기고 "실행에만 집중"하면 됨.
- DIP를 잘 지키고 있음.
- 마찬가지로 OrderServiceImpl은 구체적인 클래스에 대해서는 전혀 모르고 오로지 추상(인터페이스)에만 의존
- 생성자를 통해여 주입
- DIP를 잘 지키고 있음.
정리하자면
- AppConfig는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성
- MemberServiceImpl
- MemoryMemberRepository
- OrderServiceImpl
- FixDiscountPolicy
- AppConfig는 생성한 객체 인스턴스의 참조(레퍼런스)를 생성자를 통해 주입한다.
- MemberServiceImpl ==> MemoryMemberRepository
- OrderServiceImpl ==> MemoryMemberRepository, FixDiscountPolicy
- 객체의 생성과 연결은 AppConfig가 담당
- 관심사의 분리 : 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리되었다.
- appConfig객체는 memoryMemberRepository객체를 생성하고 그 참조값을 memberServiceImpl을 생성하면서 생성자로 전달
- 클라이언트인 memberServiceImpl 입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 DI(Dependency Injection) , 의존관계 주입, 의존성 주입이라 한다.
매 우 중 요 한 개 념 임!
ㄹㄹㄴㅇㄹㄴ
AppConfig 실행
👇
👇
- 앞서 우리가 테스트를 위해 생성한 MemberApp클래스이다.
- AppConfig객체 appConfig를 만들어 memberService를 호출한다.
- AppConfig의 memberService가 호출되며 회원 저장소 구현체가 생성되어 회원서비스 구현체에 주입된다.
- 실행시켜보면 테스트가 잘 작동하는 것을 확인할 수 있다
- 의존관계가 잘 주입되었음
- 마찬가지로 AppConfig의 orderService가 호출되어 구현체들이 생성되고 의존관계들이 주입된다.
- 의존관계 주입이 정상적으로 이루어져 테스트가 잘 작동하는 것을 확인할 수 있다.
# Junit 테스트 코드 변경
- @BeforeEach 애노테이션을 사용하여 테스트마다 실행시켜줌.
- 마찬가지로 AppConfig객체를 생성하여 의존관계 주입
테스트 성공!
반응형
'Spring > Spring Core' 카테고리의 다른 글
IoC / DI / Container (0) | 2021.03.05 |
---|---|
AppConfig 리팩토링 / 할인 정책 적용 (0) | 2021.03.05 |
정률 할인 정책 적용 / 문제점 (0) | 2021.03.04 |
새로운 할인 정책 (0) | 2021.03.04 |
주문과 할인 도메인 실행 / 테스트 (0) | 2021.03.04 |