MemberService <- MemberServiceImpl

OrderService <- OrderServiceImpl

 

MemberRepository <- MemoryMemberRepository, JdbcMemberRepository

DiscountPolicy <- FixDiscountPolicy, RateDiscountPolicy

 

 

클라이언트 -> 회원 서비스(MemberServiceImpl) -> 회원 리포지토리(MemoryMemberRepository)

 

public class MemberServiceImpl implements MemberService{
   
    private final MemberRepository memberRepository = new MemoryMemberRepository();
   
    public void join(Member member) {
        memberRepository.save(member);
    }

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

회원서비스 MemberServiceImpl는 회원 리포지토리를 사용하기 위해 MemoryRepository를 구현한 MemoryMemberRepository를 직접 new로 인스턴스 만들어서 사용 => 다형성


클라이언트 -> 주문 서비스(OrderServiceImpl) -> 회원 리포지토리, 할인금액 계산

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository = new MemoryMemberRepository();
   
    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    //private  final DiscountPolicy discountPolicy = new RateDiscountPolicy();
   
    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); // 주문 생성
    }
}

주문 서비스 OrderServiceImpl은 회원 리포지토리, 할인금액 계산을 위해서 직접 new로 인스턴스를 만들어서 사용

=> 다형성

 

 

- 두 가지 방법 모두 역할과 구현을 잘 분리하였고, 다형성을 잘 활용하여 변경사항이 있는 경우 new코드만 변경하면 됨

 

그런데, 객체 지향 원칙

1) DIP 위반 : 클라이언트는 인터페이스에 의존해야지, 구현체에 의존하면 안 된

=> MemberServiceImpl이 구현체 클래스인 MemoryMemberRepository에 의존

=> OrderSerivceImpl이 구현체 클래스인 MemoryMemberRepository, FixDiscountPolicy에 의존

 

2) OCP 위반 : 변경에는 폐쇄, 확장에는 개방

=> 멤버 리포지토리를  Memory에서 Jdbc로 변경하기 위해서는 클라이언트 코드인 MemberServiceImpl 변경 필요

=> 할인금액 계산 방법을  Fix에서 Rate로 변경하기 위해서는 클라이언트 코드인 OrderServiceImpl 변경 필요

 

 

해결방법 : 클라이언트가 구현체가 아닌 추상(인터페이스)에 의존하도록 변경

=> 외부에서 클라이언트 MemberServiceImpl, OrderSerivceImpl에게 MemberRepository, DiscountPolicy구현체 인스턴스를 대신 생성해서 주입해주면 됨