클라이언트가 구현에 의존하지 않고 역할에만 의존할 수 있도록 외부에서 대신 의존관계를 만들어주는 Java설정 클래스를 도입

 

AppConfig

public class AppConfig {
    
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    public OrderService orderService() {
        return new OrderServiceImpl(new MemoryMemberRepository(), new RateDiscountPolicy());
    }

    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public DiscountPolicy discountPolicy(){
        return new RateDiscountPolicy();
        //return new FixDiscountPolicy()
    }

}

 

MemberServiceImpl (생성자 추가)

ublic class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    public void join(Member member) {
        memberRepository.save(member);
    }

    public Member findMember(Long id) {
        return memberRepository.findById(id);
    }
}

 

OrderServiceImpl (생성자 추가)

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;
    }

    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가 클라이언트가 필요로 하는 구현체를 대신 new로 생성해서 생성자를 통해 주입해줌(의존성 주입)

- 클라이언트가 사용할 멤버 리포지토리나 할인정책을 변경하기 위해서 AppConfig만 수정하면 됨(클라이언트 수정X)

- 클라이언트는 생성자로 들어오는 구현체가 뭔지 알 필요가 없고, 이는 AppConfig에서 결정함

- 어플리케이션이 사용 영역과 구성 영역으로 분리됨

=> DIP, OCP 만족