다음의 요구사항을 보고 개발을 진행해보자.
이 때, 회원 ID, 상품명, 상품 가격이 포함됨
(주문 서비스를 DB에 저장하는 과정은 생략)
이 때, 역할과 구현을 분리해놓으면, 저장소나, 할인 정책을 쉽게 조립할 수 있기 때문에 더 좋을 수 밖에 없다.
출처 : 김영한님 스프링 강의
package Goat.core.discount;
import Goat.core.member.Member;
public interface DiscountPolicy {
//return 은 할인 대상 금액
int discount(Member member, int price);
}
package Goat.core.discount;
import Goat.core.member.Grade;
import Goat.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 ){
return discountFixAmount;
}
else{
return 0;
}
}
}
package Goat.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;
}
}
이 때, 최종 가격을 얻어내기 위해, calculatePrice함수가 추가로 작성되었다.
Integer와 int 무엇이 다른가?
앞에보면 itemPrice와 discountPrice에 Integer가 아닌 int가 쓰였다.
int : 변수형 타입 -> 산술 연산 가능, null로 초기화 불가
Integer : wrapper class 로 '객체' -> 연산을 위해 형변환 필수, null 값 처리 가능
package Goat.core.Order;
import org.springframework.core.annotation.Order;
public interface OrderService {
Order createOrder(Long memberId, String itemName, int itemPrice);
}
클라이언트에서 주문을 넣을 때 세가지 정보롤 함으로, 이 정보를 통해 주문 서비스 생성
package Goat.core.order;
import Goat.core.discount.DiscountPolicy;
import Goat.core.discount.FixDiscountPolicy;
import Goat.core.member.Member;
import Goat.core.member.MemberRepository;
import Goat.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 resultMember = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(resultMember,itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
주문 서비스 구현에는
1. 멤버들의 등급이 필요 -> repository를 받아와야 한다.
2. 할인 정책이 필요 -> discountPolicy 를 받아온다.
그리고, 여기에는 SOLID중 S(SRP-단일체계원칙)이 잘 지켜졌다.
Order에서 처리하고자 하는 것은 주문과 관련된 것들만 하는 것이지, 할인에 대한 것은 전적으로 DiscountPolicy에게 넘긴다.