Spring 핵심 원리 #2- 주문/할인 도메인 개발
Web/Java (Spring+JSP)

Spring 핵심 원리 #2- 주문/할인 도메인 개발

# 주문과 할인 정책

  - 회원은 상품을 주문 할 수 있다.

  - 회원 등급에 따라서 할인 정책을 적용할 수 있다.

     - 우선은 VIP는 1000원을 할인해주는 고정 할인금액 정책을 적용한다. (추후에 변경될수도 있다)

     - 아직 회사의 할인정책이 미정이다. 오픈 직전까지 고민을 미루고싶다.

 

-> 할인 정책을 언제든 유연하게 바꿀 수 있도록 하는 것이 중요해 보인다.

 

 

# 주문 도메인 다이어그램

 1. 주문 생성 : 고객은 주문 서비스에 주문 생성을 요청한다.

 2. 회원 조회: 할인을 위해서는 회원 조회가 필요하다. 주문 서비스는 회원 저장소에서 회원을 조회한다.

 3. 할인 적용 : 주문 서비스는 회원 등급에 따른 할인 적용을 할인 정책에 위임한다.

 4. 주문 결과 반환 : 주문 서비스는 할인 결과를 포함한 주문 결과를 반환한다.

 

 

# 주문 도메인 전체

-> 각 역할과 구현부를 철저하게 분리하여 자유롭게 할인정책/DB 정책 등에 따라 구현 객체를 자유롭게 조립할 수 있도록 설계되었다. 이 덕분에 회원 저장소는 물론이고, 할인 정책도 유연하게 변경할 수 있다.

: 각각의 클래스가 철저하게 자신의 할 일만 수행하는 단일 책임 원칙(SRP)을 잘 지키고 있음을 확인할 수 있다.

 

 

 

# 주문 도메인 클래스 다이어그램

1. OrderServiceImpl 에서 Member 정보를 조회하는 부분과 할인정책 적용 여부를 각각 MemberRepository, DiscountPolicy에 위임한 것을 확인할 수 있다.

2. 추후에 DB, 할인 정책이 결정되어도 유연한 변경이 가능하도록 클래스들을 철저히 분리해둔다.

 

 #주문 도메인 객체 다이어그램 

-> 위처럼 구현해둠을 통해 어떤 정책이 적용되어도 객체를 유연하게 조립할 수 있음을 확인가능하다.

   1) 메모리에 회원 저장 & 정액 할인 

  2) DB에 회원 저장 & 정률 할인

#개발 

 - 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);
        //discountPolicy에 의존함. 단일책임원칙을 잘 지킴=>추후 변경 시 할인 쪽만 고치면 된다. 
        //다른 클래스 부분까지 고칠 필요가 없다.
        
        return new Order(memberId,itemName,itemPrice,discountPrice);
        //주문 생성이 오면 회원 정책 적용하고, 주문을 넘겨주면 됨.
    }
}

1. member를 찾고 구현하는 부분을 모두 memberRepository에 위임하였다.

2. 할인 정책을 적용하는 부분 역시 discountPolicy에 위임하였다.

-> OrderServiceImpl에서 모든 역할,클래스를 분리하여 객체를 원하는 대로 조합하여 사용하였음을 확인할 수 있었다.

(코드 전체공개 불가 정책이 있어 일부분만 발췌하여 중요한 부분을 정리하도록 할것이다)

 

#Test

public class OrderServiceTest {
    MemberService memberService=new MemberServiceImpl();
    OrderService orderService=new OrderServiceImpl();

    @Test
    void createOrder(){
        //given
        Long memberId=1L;
        Member memberA = new Member(memberId, "memberA", Grade.VIP);

        //when
        memberService.join(memberA);
        Order order = orderService.createOrder(memberId, "itemA", 10000);

        //then
        Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);
    }
}

-> test를 통해 생성된 Order객체가 담고있는 할인가가 1000원임을 확인할 수 있다. -> 할인 정책 잘 적용됨.

 

 

#고찰

-> 주문과 할인 도메인을 설계,개발, 테스트를 진행해보면서 느낀 점은 역할과 구현부를 철저히 분리하여 유연하게 객체를 조립하여 사용할수 있도록 하는 것이 정말 중요함을 깨달았다.

 

 

 

+) 위 포스팅은 인프런 강의 김영한 팀장님의 Spring 핵심 원리 기본편을 수강하고 난 내용을 정리하였습니다.