주문과 할인 도메인 설계
2023. 7. 6. 23:00ㆍSpring/[inflearn]스프링 핵심 원리 - 기본편
◎ 비즈니스 요구 사항
<주문과 할인 정책>
- 회원은 상품을 주문한다.
- 회원 등급에 따라 등급에 해당하는 할인을 적용받을 수 있다.
- 모든 VIP등급의 회원은 1000원을 할인해준다.(임시 정책으로 이후에 변경 가능성이 있다.)
◎ 주문 도메인 설계
-> 위 도메인 설계를 기반으로 아래와 같이 인터페이스와 클래스를 구현한다.
◎ 주문 도메인 개발
-> 할인 정책 인터페이스
/**
* <할인 정책 인터페이스>
*/
public interface DiscountPolicy {
int discount(Member member, int price); // 할인 대상 금액 리턴
}
-> 정액 할인 정책(할인 정책 인터페이스의 구현 클래스)
/**
* <정액 할인 정책>
* 회원등급이 VIP인 회원에 대해 1000원 할인
*/
public class FixDiscountPolicy implements DiscountPolicy{
private final int discountFixAmount = 1000; // 할인 금액 : 1000원
@Override
public int discount(Member member, int price) {
if (member.getGrade() == Grade.VIP) {
return discountFixAmount; // 회원 등급이 VIP면 1000원 할인 적용
}else{
return 0;
}
}
}
-> 주문 엔티티 클래스
/**
* <주문 엔티티>
*/
public class Order {
private Long memberId; // 주문한 회원의 id
private String itemName; // 주문 상품 이름
private int itemPrice; // 상품 가격
private int discountPrice; // 할인 가격
public Order(Long memberId, String itemName, int itemPrice, int discountPrice) {
this.memberId = memberId;
this.itemName = itemName;
this.itemPrice = itemPrice;
this.discountPrice = discountPrice;
}
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemPrice() {
return itemPrice;
}
public void setItemPrice(int itemPrice) {
this.itemPrice = itemPrice;
}
public int getDiscountPrice() {
return discountPrice;
}
public void setDiscountPrice(int discountPrice) {
this.discountPrice = discountPrice;
}
@Override
public String toString() {
return "Order{" +
"memberId=" + memberId +
", itemName='" + itemName + '\'' +
", itemPrice=" + itemPrice +
", discountPrice=" + discountPrice +
'}';
}
}
-> 주문 서비스 인터페이스
/**
* <주문 서비스 인터페이스>
*/
public interface OrderService {
Order createOrder(Long memberId, String itemName, int itemPrice); // 주문 생성
}
-> 주문 서비스 구현 클래스
/**
* <주문 서비스 구현 클래스>
*/
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);
}
}
- 현재 구현된 주문 서비스 구현 클래스에서 구현 클래스인 MemoryMemberRepository와 FixDiscountPolicy를 의존하고 있다.
- 위 코드처럼 구현을 하면 회원 정보를 저장하는 방식을 바꾸거나 할인 정책이 바뀌게 되면 해당 코드를 직접 변경해야 한다.
- 위 코드는 DIP와 OCP를 모두 위반하였다.
- 이 문제는 주문 관련 코드까지 만들고 나서 이후에 수정할 계획이다.
-> 주문 및 할인 정책 적용 테스트
/**
* <주문 및 할인 정책 테스트>
*/
public class OrderServiceTest {
MemberService memberService = new MemberServiceImpl();
OrderService orderService = new OrderServiceImpl();
@Test
@DisplayName("주문 및 할인 정책 테스트")
void createOrder(){
Long memberId = 1L;
Member member = new Member(memberId, "memberA", Grade.VIP); // 등급인 VIP인 memberA라는 회원
memberService.join(member); // 회원 가입
Order order = orderService.createOrder(memberId, "itemA", 10000); // 주문 생성
Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000); // 할인된 금액이 1000원이 맞는지 검증
}
}
- 회원 등급이 VIP인 회원이 물건을 주문했을 때 1000이 할인되는지 검증한다.
-> 결과
- 테스트에 통과했다. 작성한 로직이 정상적으로 동작한 것을 알 수 있다.
☆ 참고
'Spring > [inflearn]스프링 핵심 원리 - 기본편' 카테고리의 다른 글
객체 지향 원리 적용 - 관심사의 분리 (0) | 2023.07.10 |
---|---|
새로운 할인 정책 개발 (0) | 2023.07.09 |
비즈니스 요구 사항 정리 및 회원 관련 서비스 설계 (0) | 2023.07.06 |
좋은 객체 지향 설계의 5원칙 - SOLID (0) | 2023.06.27 |
객체 지향 설계와 스프링 (0) | 2023.06.26 |