Spring-2021.12.04

Jonguk Kim·2021년 12월 4일
0

Spring 강의

목록 보기
5/7

1. 새로운 할인 정책 개발

  • RateDiscountPolicy 추가
public class RateDiscountPolicy implements DiscountPolicy{

    private int discountPercent = 10;	// 10% 할인

    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP){
            return price * discountPercent / 100;
        } else {
            return  0;
        }
    }
}

2. 새로운 할인 정책 테스트

class RateDiscountPolicyTest {

    RateDiscountPolicy discountPolicy = new RateDiscountPolicy();

    @Test
    @DisplayName("VIP는 10% 할인이 적용되어야 한다")
    void vip_o(){
        // given
        Member member = new Member(1L, "memberVip", Grade.VIP);

        // when
        int discount = discountPolicy.discount(member, 10000);

        // then
        assertThat(discount).isEqualTo(1000);
    }

    @Test
    @DisplayName("VIP가 아니면 할인이 적용되지 않아야 한다")
    void vip_x(){
        // given
        Member member = new Member(2L, "memberBASIC", Grade.BASIC);

        // when
        int discount = discountPolicy.discount(member, 10000);

        // then
        assertThat(discount).isEqualTo(0);
    }

}

3. 문제점

  • DIP 위반: 추상(인터페이스) 뿐만 아니라 구체(구현) 클래스에도 의존하고 있다.
    • 추상(인터페이스) 의존: DiscountPolicy
    • 구체(구현) 클래스: FixDiscountPolicy , RateDiscountPolicy
  • OCP 위반: 지금 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 준다
    • FixDiscountPolicy 를 RateDiscountPolicy 로 변경하는 순간 OrderServiceImpl 의 소스 코드도 함께 변경해야 한다

4. 해결

  • 인터페이스에만 의존하도록 설계를 변경 -> 구현체가 없기 때문에 NPE(null pointer exception)가 발생
public class OrderServiceImpl implements OrderService{

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

=> 누군가가 클라이언트인 OrderServiceImpl 에 DiscountPolicy 의 구현 객체를 대신 생성하고 주입해주어야 한다.

profile
Just Do It

0개의 댓글