당니의 개발자 스토리

주문과 할인 도메인 개발 본문

스프링/스프링 핵심 원리 - 기본편

주문과 할인 도메인 개발

clainy 2024. 1. 17. 14:51

주문과 할인 도메인 개발

이번 시간에는 주문과 할인 도메인을 개발해 보겠습니다.

먼저, 할인 정책이 들어가야 되겠죠. 패키지를 하나 만들 겁니다.

hello.core 밑에다가 dicount 패키지를 만들고요, 그 다음에 여기에다가

DiscountPolicy(할인정책) 라는 interface를 만들 겁니다. 그리고 얘는 discount 라는 메서드만 있어요.

파라미터로는 memberprice를 넘길 겁니다. 여기서 좋은 단축키, F2를 누르면 에러난 곳으로 바로 이동합니다. 그리고나서 만능 option + enter를 누르면 됩니다.

그리고 주석으로 return이 할인 대상 금액이라고 적어요. 이 discount 메서드를 호출하고 나면, 그 결과로 할인한 금액을 리턴해줍니다.

그러면 이제 이거에 대한 구현체를 만들어야되죠.

FixDiscountPolicy 라는 클래스를 만들어서, 정액 할인 정책 구현체를 만들 겁니다.

우리는 무조건 1,000원을 할인해줄 거니깐,

이렇게 변수를 선언합니다. 그런데 할인을 하려면 조건이 있었죠?

등급이 VIP이어야 합니다.

그런데 여기 이렇게 == 써도 되는 걸까요? 됩니다. enum ==을 쓰는게 맞습니다.

그리고나서, VIP이면 할인금액을 1000원 반환합니다.

VIP가 아니면, return 0; 해줍니다.


그 다음에 주문 쪽을 만들겠습니다. 이번에는 order 라는 패키지를 만들겠습니다.

그리고 여기다가 Order 라는 클래스를 만듭니다.

뒤에서 이 기능을 수행하기 위해서 이 3가지 속성을 담을 주문 Entity 만드는 것이기 때문에 interface로 구현할 필요가 없습니다. 그리고나서,

필드에 멤버 아이디 만들고, 아이템 이름, 그리고 주문을 할 때 아이템 가격, 그리고 할인 금액을 선언했습니다.

그리고 생성자를 만들어서 OK 하면,

이렇게 됩니다. 그러니까 주문하고 할인까지 다 끝냈을 때 만들어지는 객체라고 보시면 됩니다.

그리고 private으로 선언했기 때문에, getter, setter를 만들어줘야 합니다.

Ok하면,

잘 만들어졌습니다. 그 다음에 비즈니스 계산 로직을 하나 넣을 겁니다.

계산된 결과를 반환하는 메서드죠.

그리고 출력할 때 보기 쉽게 하기 위해서, toString()을 부를 거예요.

해서,

Ok 하면,

이 객체를 출력하면, toString의 결과가 쭉 나옵니다.

예를 들어서, 우리가 만약에

이렇게 order라는 객체 자체를 출력하면, 그럼 거기에 있는 toString이 호출이 되거든요. 그래서 이렇게 말고, 편하게 데이터를 볼 수 있게

이렇게 남겨놨습니다.


그리고 이제 주문 서비스 인터페이스를 만들겠습니다.

order 패키지 안에 OrderService 라는 인터페이스를 만들고,

retrun 값이 Order이면서 회원id와 상품명, 상품가격을 파라미터로 받는 메서드를 만들 겁니다.

이걸 보면,

지금 1번과 4번의 기능을 구현한 겁니다. 주문을 생성할 때, 회원id, 상품명, 상품 가격을 파라미터로 넘기면, 주문 결과를 return으로 반환한다고 했었습니다. 최종 Order 결과를 반환하는 게

이 메서드입니다. 그래서 이렇게 주문 서비스 인터페이스를 만든 겁니다. 주문을 생성하고 주문 결과를 반환하는 역할을 만든 거죠.


이제 주문 서비스 구현체를 만들어야 합니다. 어쩌면 이제부터가 핵심입니다.

OrderServiceImpl 클래스를 만들어서, 인터페이스니까 implements 해서 구현 메서드를 override 해야합니다.

OrderServiceImpl는 2개가 필요합니다. 회원을 찾아야하니까 회원 저장소가 필요하고, 할인정책이 어떻게 적용되는지도 알아야하므로, 할인 정책도 필요합니다.

이렇게 필드를 작성해줍니다.

이제 쉽습니다. 가장 먼저 파라미터로 들어온 회원id를 사용해서 회원 저장소에 있는 member를 찾아야 합니다.

주문을 한 회원을 id로 찾는 거에요.

그 다음에 DiscountPolicy에다가 "난 잘 모르겠으니까, 이 회원한테 할인을 얼마나 해줄지 너가 찾아줘!" 하고 DiscountPolicydiscount 메서드를 호출하는 겁니다.

이게 설계가 굉장히 잘 된거에요.

이게 왜 설계가 잘됐다고 보냐면, OrderService 입장에서는 할인에 대한 건 하나도 모르지만, DiscountPolicy가 알아서 해주도록 설계를 한 거에요. 그러니까 이게 단일 책임 원칙(SRP)을 잘 지킨 겁니다.

만약에 할인에 대한 변경이 필요하면, 할인 쪽만 고치면 되잖아요. 주문 쪽까지 같이 고칠 필요가 없죠. 이게 굉장히 중요합니다.

자 이제 Order를 만들어서 반환 해주면 되죠.

이렇게 주문을 만들어서 반환을 해주기만 하면, OrderService의 역할이 끝납니다.

이렇게 해서 주문 생성 요청이 오면, 회원 정보를 먼저 조회하고, 그 다음에 할인 정책에다가 회원을 그냥 넘기는 거에요. 물론 등급만 넘겨도 되지만, 미래의 확장성이랑 몇 가지를 고려해서 Member를 통으로 넘기도록 구현했습니다. 이렇게 해서 최종적으로 할인된 가격을 받았습니다.

그리고 최종 생성된 주문을 반환을 했죠.

그래서 지금 여기서는 메모리 회원 리포지토리와 고정할인 금액 정책을 구현체로 생성해서 사용을 하고 있습니다.


그러면 다음 시간에는 주문 할인 도메인을 실행하고 테스트 해볼게요.