[Spring-기본] 주문, 할인 도메인 설계(순수 자바로 만들기)

DANI·2023년 11월 21일

Spring[김영한T]

목록 보기
13/31
post-thumbnail

📑 비즈니스 요구사항 설계


📩 주문과 할인 정책

  • 회원은 상품을 주문할 수 있다.
  • 회원 등급에 따라 할인 정책을 적용할 수 있다.
  • 할인 정책은 모든 VIP는 1000원을 할인해주는 고정 금액 할인을 적용(나중에 변경 가능)
    👉 할인 정책은 변동가능성이 높으며, 최악의 경우 할인을 적용하지 않을 수 있다.

할인 정책은 인터페이스를 만들고 구현체를 갈아 끼울 수 있도록 설계





주문 도메인 협력 관계


실제로는 주문 데이터를 DB에 저장함



주문 도메인 전체




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




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




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






🔴 클래스 다이어그램 구현해보기

💾 Order 클래스 생성

package hello.core.Order;

import hello.core.member.Member;

public class Order {
    private Long id;
    private String name;
    private int price;
    private int disPrice; // 할인액

    public Order(Long id, String name, int price, int disPrice) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.disPrice = disPrice;
    }

    /*
     *  할인 적용된 금액
    */
    public int calprice(){
        return price - disPrice;
    }
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public int getDisPrice() {
        return disPrice;
    }

    public void setDisPrice(int disPrice) {
        this.disPrice = disPrice;
    }


    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", disPrice=" + disPrice +
                '}';
    }
}

💾 OrderService 인터페이스 생성

package hello.core.Order;

import hello.core.member.Member;

public interface OrderService {
    Order createOrder(Long id, String name, int price);
}

💾 OrderServiceImpl 구현체 생성

package hello.core.Order;

import hello.core.Discount.DiscountPolicy;
import hello.core.Discount.FixedDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository = new MemoryMemberRepository();
    private final DiscountPolicy discountPolicy = new FixedDiscountPolicy();


    @Override
    public Order createOrder(Long id, String name, int price) {
        Member member = memberRepository.findById(id);
        int discount = discountPolicy.fixedDiscount(member, price);
        return new Order(id, name, price, discount);
    }
}


💾 DiscountPolicy 인터페이스 생성 (fixedDiscount)

package hello.core.Discount;

import hello.core.member.Member;


public interface DiscountPolicy {
     
     /*
     * 할인액
     * */
     int fixedDiscount(Member member, int price);
}

💾 FixedDiscountPolicy 구현체 생성

package hello.core.Discount;

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

public class FixedDiscountPolicy implements DiscountPolicy{

    private  int discountFixAmount = 1000; // 1000원 할인

    @Override
    public int fixedDiscount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){
            return discountFixAmount;
        }else {
            return 0;
        }
    }
}





✅ 주문 도메인 테스트 해보기

1. OrderApp 파일로 실행해보기

💾 OrderApp 파일 생성

package hello.core;

import hello.core.Order.Order;
import hello.core.Order.OrderService;
import hello.core.Order.OrderServiceImpl;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;

public class OrderApp {
    public static void main(String[] args) {
        MemberService memberService = new MemberServiceImpl();
        OrderService orderService = new OrderServiceImpl();

        // 멤버 생성
        Long id = 1L;
        Member member = new Member(id, "홍길동", Grade.VIP);
        memberService.join(member);

        // 주문 생성
        Order order = orderService.createOrder(1L, "새우깡", 1700);


        // 주문 내용 출력
        System.out.println(order);
        System.out.println(order.calprice());

    }
}

🔴 실행결과

Order{id=1, name='새우깡', price=1700, disPrice=1000}
700

Process finished with exit code 0

2. OrderServiceTest 실행해보기

💾 OrderServiceTest 파일 생성

package hello.core.Order;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class OrderServiceTest {

    MemberService memberService = new MemberServiceImpl();
    OrderService orderService = new OrderServiceImpl();

    @Test
    void createOrder(){
        Long id = 1L;
        Member member = new Member(id, "홍길동", Grade.VIP);
        memberService.join(member);

        Order order = orderService.createOrder(1L, "새우깡", 1800);
        Assertions.assertThat(order.getDisPrice()).isEqualTo(1000);

    }
}

🔴 실행결과





💡 정률할인정책등 새로운 할인 정책이 생겼을 때?



💡 해결방안

0개의 댓글