AppConfig
- 애플리케이션의 전체 동작 방식을 구성(config)하기 위해, “구현 객체를 생성” 하고, “연결”하는 책임을 가지는 별도의 설정 클래스
- DIP 원칙을 지킬 수 있게 도와준다.
Appconfig.class
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(new MemoryMemberRepository(),
new FixDiscountPolicy());
}
}
- AppConfig 는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성
- MemberServiceImpl
- MemoryMemberRepositroy
- OrderServiceImpl
- FixDiscountPolicy
- AppConfig 는 생성한 객체 인스턴스의 참조를 생성자를 통해서 주입
- MemberServiceImpl → MemoryMemberRepository
- OrderServiceImpl → MemoryMemberRepository, FixDiscountPolicy
MemberServiceImpl.class
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
- 구현체를 의존하지 않는다.
- 오로지 인터페이스에만 의존한다.
- DIP 원칙 ✅
OrderServiceImpl.class
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;
}
}
- 구현체를 의존하지 않는다.
- 오로지 인터페이스에만 의존한다.
- DIP 원칙 ✅
구현체 입장
- 생성자를 통해 어떤 구현 객체가 들어올지 (주입 될지) 알 수 없다.
- 어떤 구현 객체를 주입할지는 오직 외부 AppConfig 에서 결정
- 의존 관계에 대한 고민은 외부에 맡기고 실행에만 집중 가능
AppConfig 담당
- 객체의 생성과 연결은 AppConfig 가 담당한다.
- DIP 완성 : 이제 구체 클래스를 몰라도 된다.
- 관심사의 분리: 객체를 생성하고 연결하고 역할과 실행하는 역할이 명확히 분리
객체 인스턴스
- appConfig 객체는 memoryMemberRepository 객체를 생성하고 그 참조 값을 memberServiceImpl 을 생성하면서 생성자로 전달한다.
- 클라이언트인 memberServiceImpl 입장에서 보면
의존관계를 마치 외부에서 주입해주는 것 같다고 해서
DI (Dependency Injection)
의존관계 주입 또는 의존성 주입이라고 한다.