Development/Spring Boot

[Spring Boot] 주문과 할인 도메인 설계 (3-1) 주문과 할인 도메인 개발

sky Jeong 2022. 8. 1. 23:51

1- 강의 내용 요약

  • 해당 강의의 요구사항을 요약하자면

    클라이언트가 주문을 넣어. 그러면 회원 아이디, 상품명, 가격이 넘어가는데 주문 서비스에서 이를 받아 주문 내역을 넘겨줘.
    근데 중요한건 회원이 VIP 등급이라면 할인 정책이 적용될수도 있는데 이게 정율일지 정액일지는 몰라.

2- 구현

  • 핵심 포인트는 역할과 구현체를 분리하는 것인데.
    (여러번 강조되지만 기능의 교체나 확장을 용이하게하기 위함)
  • 여기서 보면 주문 구현체는 주문 생성만 행하고 있고, 할인정책 구현체는 할인 정책만 넘겨주고 있기에 단일 책임 원칙(SRP)가 매우 잘지켜지고 있음. 
  • 예시 코드의 전제조건은 'VIP는 정액법으로 1,000원을 할인한다.'인데, 이게 아닌 정율법으로 바뀐다하여도 주문 구현체를 수정할 필요가 없기에. 즉, 각 구현체와 역할들이 본인의 역할에 충실해 다른 기능의 변화가 있어도 영향을 받지 않아 단일 책임 원칙이 잘 지켜졌다는 것.

 

> 할인 구현체 중 정액법 구현체

package hello.core.discount;

import hello.core.member.Grade;
import hello.core.member.Member;

public class FixDiscountPolicy implements DiscountPolicy{

    // VIP에게는 무조건 1,000원을 할인해준다.
    private int discountFixAmount = 1000;

    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP) // Enum type은 ==을 쓰는게 맞음
            return discountFixAmount;
        else
            return 0;
    }

}

 

> 주문 구현체

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;

public class OrderServiceImpl implements OrderService{

    private MemberRepository memberRepository = new MemoryMemberRepository();
    private DiscountPolicy discountPolicy = new FixDiscountPolicy();

    /**
     * 해당 설계가 잘된 이유: 단일 책임 원칙 (SRP)이 잘 지켜짐
     *  OrderService는 할인 정책에 대해 모름.
     *  좀더 풀어서 이야기하자면, 주문쪽에서 굳이 할인 정책에 대해 확인하고 까보지 않아도됨.
     *
     *  그렇기에 할인이 수정이 이루어져도 주문은 수정할 필요가 없기에 단일 책임 원칙이 잘 지켜짐
     *
     * @param memberId
     * @param itemName
     * @param itemPrice
     * @return
     */
    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {

        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(member.getId(), itemName, itemPrice, discountPrice);

    }

}