// OrderServiceImpl 클래스는 MemberRepository 인터페이스와 구현체인 MemoryMemberRepository // DiscountPolicy 인터페이스와 구현체인 RateDiscountPolicy 를 의존하는 문제점이 있다. privatefinalMemberRepositorymemberRepository=newMemoryMemberRepository(); privatefinalDiscountPolicydiscountPolicy=newRateDiscountPolicy();
@Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Membermember= memberRepository.findById(memberId); intdiscountPrice= discountPolicy.discount(member, itemPrice);
DiscountPolicy 의 구현체가 FixDiscountPolicy 에서 RateDiscountPolicy 로 바뀌게 되면 OrderServiceImpl 에서 FixDiscountPolicy를 RateDiscountPolicy로 변경하기 위해서 코드를 수정해줘야 한다.
// FixDiscountPolicy 에서 RateDiscountPolicy 로 구현체를 변경하기 위해서는 Client 코드를 변경해야 하는 문제점이 있다. // private final DiscountPolicy discountPolicy = new FixDiscountPolicy(); privatefinalDiscountPolicydiscountPolicy=newRateDiscountPolicy(); @Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Membermember= memberRepository.findById(memberId); intdiscountPrice= discountPolicy.discount(member, itemPrice);
애플리케이션의 전체 동작방식을 구성하기 위해 구현 객체 생성 및 연결 을 위한 별도의 설정 class 를 만들어준다.
관심사의 분리가 이루어지게 됐다. –> 객체 생성 및 연결과 실행하는 부분의 logic이 분리가 됐다.
AppConfig 클래스 내의 memberService 메소드는 MemberService의 구현체인 MemberServiceImpl를 반환한다. MemberServiceImpl 객체를 생성할 때 MemberRepository의 구현체인 MemoryMemberRepository 객체를 주입해준다.
MemberServiceImpl 생성자를 통해 MemoryMemberRepository 객체를 주입해주는 것을 생성자를 통한 의존성 주입이라 한다.
AppConfig.java
publicclassAppConfig {
// memberService 메소드에서 MemberServiceImpl 객체 생성 및 MemberRepository 객체에 대한 의존성 주입을 해준다. // 의존성 주입시 인터페이스 및 추상 클래스에 대한 구현 객체가 들어가기 된다. MemoryMemberRepository public MemberService memberService(){ returnnewMemberServiceImpl(newMemoryMemberRepository()); }
// orderService 메소드에서 OrderServiceImpl 객체 생성 및 MemberRepository 객체와 DiscountPolicy 객체에 대한 의존성 주입을 한다. public OrderService orderService(){ returnnewOrderServiceImpl(newMemoryMemberRepository(), newFixDiscountPolicy()); } }
의존성을 주입 받기 위한 방법으로 생성자를 만들어 줬다.
MemberServiceImpl 는 객체 생성시 외부로부터 MemberRepository 에 대한 의존성을 주입 받게 된다.
MemberRepository 에 대한 구현 클래스 관리는 더 이상 MemberServiceImpl 에서 관리하지 않고 외부에서 관리하게 됐다.
MemberServiceImpl 는 이제 MemberRepository 인터페이스에만 의존하게 되므로 DIP 원칙을 지키게 됐다.
@Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Membermember= memberRepository.findById(memberId); intdiscountPrice= discountPolicy.discount(member, itemPrice);
MemberServiceImpl와 OrderServiceImpl는 인터페이스에만 의존하게 함으로 코드상으로는 어떤 구현 객체가 들어올지는 알 수 없고, 생성자를 통해 외부에서 구현객체를 주입 받게 된다.
AppConfig를 통해 객체의 생성과 연결을 진행 하고 MemberServiceImpl와 OrderServiceImpl는 실행만 하면 되므로 역할이 분리가 됐다. 또한 외부에서 MemberServiceImpl와 OrderServiceImpl에 구현객체를 넣어주는 것을 보고 의존성 주입이라 한다.
AppConfig 리펙터링
AppConfig.java
publicclassAppConfig {
public MemberService memberService(){ returnnewMemberServiceImpl(memberRepository()); }