본문 바로가기
JAVA & SPRING/Spring 핵심원리-기본

스프링 핵심 원리 기본편-2일차(스프링 핵심원리 이해1 - 주문 & 할인 도메인)

by 눈오는1월 2023. 7. 24.
728x90

회원 도메인을 만들었으니 이제 주문과 할인 도메인을 설계하고 개발할 것이다.

그전 글과 이번 도메인을 다 합치면 

이와 같은 설계를 그릴 수 있다.

 

이제 할인정책을 개발해보자

hello.core에 discount 패키지를 만들고, DiscountPolicy 인터페이스를 만든다.

package hello.core.discount;

import hello.core.member.Member;

public interface DiscountPolicy {

    /*
     * @return 할인 대상 금액
     */
    int discount(Member member, int price);
}

그후 이 인터페이스를 상속받는 FixDiscountPolicy 클래스를 만든다.

package hello.core.discount;

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

public class FixDiscountPolicy implements DiscountPolicy {

    private int discountFixAmount = 1000; //1000원 할인
    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){ //Enum타입은 == 쓰는게 맞음
            return discountFixAmount;
        } else {
            return 0;
        }
    }
}

할인이 완성됐으니 이제 주문하는 부분을 개발한다.

discount와 같은경로에 order 패지키를 만들고 Order클래스를 만든다.

package hello.core.order;

public class Order {

    private Long memberId;
    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 int calculatePrice(){ // 계산된 결과
        return itemPrice - 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() {  // 객체를 출력했을때 toString 의 결과가 출력됨
        return "Order{" +
                "memberId=" + memberId +
                ", itemName='" + itemName + '\'' +
                ", itemPrice=" + itemPrice +
                ", discountPrice=" + discountPrice +
                '}';
    }
}

Order객체를 만들었으니 주문기능 서비스를 만들어야한다.

OrderService 인터페이스를 만든다.

package hello.core.order;

public interface OrderService {
    Order createOrder(Long memberId, String itemName, int itemPrice);
}

이제 OrderService를 상속받는 OrderServiceImpl 클래스 를 만든다

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 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);
    }
}

 

저번과 마찬가지로 CoreApplication와 같은 경루에 orderApp을 만들어서 잘 돌아가는지 확인

package hello.core;

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

public class orderApp {

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

        Long memberId = 1L;
        Member member = new Member(memberId, "memberA" , Grade.VIP);
        memberService.join(member);

        Order order = orderService.createOrder(memberId,"itemA", 10000);

        System.out.println("order = " + order.toString());
        System.out.println("order.calculatePrice = " + order.calculatePrice());
    }
}

실행결과인데 마찬가지로 눈으로 확인해야 하기때문에 test를 이용해서 제대로 돌아가는지 확인

test에 order 패키지를 만든 후에 orderApplicationTest를 만든다.

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 memberId = 1L;  //null 들어갈 수 있게 Long으로 함(참조타입 사용)
        Member member = new Member(memberId, "memberA", Grade.VIP);
        memberService.join(member);

        Order order = orderService.createOrder(memberId, "itemA", 10000);
        Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);

    }
}

이것으로 테스트가 잘 작동되는지 확인한다.

728x90