새로운 할인 정책 개발
2023. 7. 9. 19:58ㆍSpring/[inflearn]스프링 핵심 원리 - 기본편
◎ 요구 사항 변경
-> 기존에 적용하던 할인 정책은 VIP 등급인 모든 회원에게 1000원을 할인해주는 정액할인 정책이다. 여기에서 주문 금액당 할인을 해주는 정률할인 정책으로 변경한다.
-> RateDiscountPolicy 클래스 생성(정률 할인 정책 구현 클래스)
/**
* <정률 할인 정책>
* VIP인 고객의 주문 금액의 10% 할인 적용
*/
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;
}
}
}
-> 할인 정책 테스트
/**
* <정률 할인 정책 테스트>
*/
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(1L, "memberVIP", Grade.BASIC);
// when
int discount = discountPolicy.discount(member, 10000);
// then
assertThat(discount).isEqualTo(0);
}
}
-> 결과
◎ 문제점
-> 현재 할인 정책 구현 클래스로 FixDiscountPolicy와 RateDiscountPolicy가 있다. 이 둘 중 하나를 선택하여 적용을 하려면 OrderServiceImpl 클래스에서 코드를 직접 수정해야 한다.
public class OrderServiceImpl implements OrderService{
//회원 저장소와 할인 정책을 의존할 때 각 인터페이스의 구현 클래스에 의존한다.
private final MemberRepository memberRepository = new MemoryMemberRepository();
// 할인 정책을 변경하려면 이 코드를 직접 수정해야 한다.
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
@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);
}
}
-> 이 코드는 추상(DiscountPolicy 인터페이스)에도 의존하고 구현체(Fix/RateDiscountPolicy)에도 의존하고 있다. 따라서 이 코드는 DIP를 위반한다.
-> 또한 할인정책을 변경하려면 OrderServiceImpl의 코드를 직접 변경해야 한다. 따라서 OCP를 위반한다.
-> 추상에만 의존하도록 의존관계를 변경해야 한다.
public class OrderServiceImpl implements OrderService{
//회원 저장소와 할인 정책을 의존할 때 각 인터페이스의 구현 클래스에 의존한다.
private final MemberRepository memberRepository = new MemoryMemberRepository();
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final 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에서 추상에만 의존하도록 코드를 변경했다. 하지만 구현체가 아닌 추상에만 의존한 상태라서 실행을 하면 NPE가 발생한다.
-> 이 문제를 해결하기 위해서는 OrderServiceImpl에 DiscountPolicy의 구현 객체를 생성하고 주입하는 역할이 필요하다.
☆ 참고
'Spring > [inflearn]스프링 핵심 원리 - 기본편' 카테고리의 다른 글
IOC / DI (0) | 2023.07.11 |
---|---|
객체 지향 원리 적용 - 관심사의 분리 (0) | 2023.07.10 |
주문과 할인 도메인 설계 (0) | 2023.07.06 |
비즈니스 요구 사항 정리 및 회원 관련 서비스 설계 (0) | 2023.07.06 |
좋은 객체 지향 설계의 5원칙 - SOLID (0) | 2023.06.27 |