프로그램의 제어 권한을 개발자인 내가 갖는게 아니라, 특정 프레임워크등이 가져가는 것.
구현 객체는 자신의 로직을 실행하는 역할만 담당하고, 프로그램에 대한 제어는 AppConfig가 가져간다.
OrderServiceImpl은 DiscountPolicy 인터페이스를 호출하지만, 어떤 구현 객체가 실행될지는 모른다(AppConfig가 전담)
심지어 이 OrderServiceImpl도 AppConfig에 의해 생성된다.
이처럼, 프로그램의 제어 흐름을 직접 제어 하는 것이 아니라 외부(AppConfig)에서 제어하는 것이 제어의 역전 이다.
프레임워크 : 프레임워크가 내가 작성한 코드를 제어하고, 대신 실행한다
- Junit의 경우. 나는 코드만 작성하고 내부 테스트 실행은 Junit에 의해 이뤄진다
라이브러리 : 내가 작성한 코드가 직접 제어의 흐름을 담당
OrderServiceImpl은 DiscountPolicy 인터페이스에 의존한다, 실제 어떠한 구현 객체가 사용될지는 모른다.
: 클래스가 사용하는 import 코드만 보고도 의존관계를 쉽게 판단할 수 있다. 애플리케이션을 실행 않고, 코드만 보고도 알 수 있다.
/* OrderServiceImpl */
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서, 클라이언트와 서버의 실제 의존 관계가 연결되는 것이 의존관계 주입
AppConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해 주는 것을 IOC 또는 DI컨테이너라고 한다.