본문 바로가기
스프링

스프링 핵심 원리 - (4)

by 공부 안하고 싶은 사람 2022. 8. 3.
반응형

새로운 정책 등장

  • 악덕 기획자: 서비스 오픈 직전에 할인 정책을 지금처럼 고정 금액 할인이 아니라 좀 더 합리적인 주문 금액당 할인하는 정률% 할인으로 변경하고 싶어요. 예를 들어서 기존 정책은 VIP가 10000원을 주문하든 20000원을 주문하든 항상 1000원을 할인했는데, 이번에 새로 나온 정책은 10%로 지정해두면 고객이 10000원 주문시 1000원을 할인해주고, 20000원 주문시에 2000원을 할인해주는 거에요!
  • 순진 개발자: 제가 처음부터 고정 금액 할인은 아니라고 했잖아요.
  • 악덕 기획자: 애자일 소프트웨어 개발 선언 몰라요? “계획을 따르기보다 변화에 대응하기를
  • 순진 개발자: … (하지만 난 유연한 설계가 가능하도록 객체지향 설계 원칙을 준수했지 후후)

 

 

새로운 할인 정책 구현체

public class RateDiscountPolicy implements DiscountPolicy{
    private int discountPercent = 10;
​
    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP) {
            return price * discountPercent / 100;
        } else {
            return 0;
        }
    }
}

테스트

class RateDiscountPolicyTest {
    RateDiscountPolicy discountPolicy = new RateDiscountPolicy();
​
    @Test
    @DisplayName("VIP는 10% 할인이 적용되어야 한다.")
    void vip_o() {
        Member member = new Member(1L, "memberVIP", Grade.VIP);
        int discount = discountPolicy.discount(member, 10000);
        assertThat(discount).isEqualTo(1000);
    }
​
    @Test
    @DisplayName("VIP가 아니면 할인이 적용되지 않아야 한다.")
    void vip_x() {
        Member member = new Member(2L, "memberBASIC", Grade.BASIC);
        int discount = discountPolicy.discount(member, 10000);
        assertThat(discount).isEqualTo(0);
    }
}

주문 로직에서 의존 구현체 변경

public class OrderServiceImpl implements OrderService {
​
    private final MemberRepository memberRepository = new MemoryMemberRepository();
    //private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
​
    @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);
    }
}

DIP: 주문서비스 클라이언트( OrderServiceImpl )는 DiscountPolicy 인터페이스에 의존하면서 DIP를 지킨 것 같은데?

  • 클래스 의존관계를 분석해 보자. 추상(인터페이스) 뿐만 아니라 구체(구현) 클래스에도 의존하고 있다.
  • 추상(인터페이스) 의존: DiscountPolicy
  • 구체(구현) 클래스: FixDiscountPolicy , RateDiscountPolicy

OCP: 변경하지 않고 확장할 수 있다고 했는데!

  • 지금 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 준다(구현체 코드 변경 필요)! 따라서 OCP를 위반한다.

 

 

따라서 인터페이스만 의존할 수 있도록 변경

public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository = new MemoryMemberRepository();
    // 인터페이스만. 단, NPE 발생한다. (빈(객체) 주입 안했으니까)
    private DiscountPolicy discountPolicy;
​
    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        ...
    }
}
 

 

728x90
반응형

'스프링' 카테고리의 다른 글

스프링 핵심 원리 - (6)  (0) 2022.08.04
스프링 핵심 원리 - (5)  (0) 2022.08.04
스프링 핵심 원리 - (3)  (0) 2022.08.03
스프링 핵심 원리 - (2)  (0) 2021.09.10
스프링 핵심 원리 - (1)  (0) 2021.09.10

댓글