본문 바로가기

개발하다 생긴 일

perfect dish | 이거 만들어볼까? (8) - 돈(Money)타입과 주문 플로우

728x90

🍽 Perfect dish 개발 일지

이 글은 개발 여정을 기록한 것으로 틀린 내용이 나올 수 있습니다. 점점 고쳐나가기 때문이죠 

 

 

 

💡 타입을 통일할 것인가 리소스를 챙길 것인가 

 

메뉴의 갯수는 int , 가격은 Null이 있을 수 있어서 Integer, 계산은 추후에 소수점 연산이 필요할 수 있으므로 정밀한 타입 BigDecimal  이렇게 하기로 했다. 근데 만약에 타입을 통일하면? 타입 컨버터 같은 걸 만들지 않아도 되니까 ^^... 헤헤 관리하기 쉬울 거 같았다. 그래서 무조건 돈 관련 타입을 BigDecimal로  ...? 😀

우리(나)가 살펴야 할 것은 타입을 통일한다면 정확성을 보장하겠지만 ~

우린 토이 프로젝트니까 리소스최적화를 위해 BigDecimal최소한으로 사용하기로 하자. 

 

 

💡 최종 주문서 까지의 여정 

 

 

Order을 둘로 나누다,  OrderItem / Order 

 

Order의 플로우는 아래와 같다.
주문하려는 메뉴를 orderRequest를 통해 전달받는다.
메뉴가 메뉴보드에 있나? 
있다면 새로운 Order 객체를 만들고 주문 리스트에 order객체를 최종 등록한다. 

그런데 추가 주문을 한다면? 

주문리스트에 같은 테이블 번호로 order객체가 계속 만들어질 것이다. 

주문 목록은 어떻게 관리하면 좋을까? 

처음에는 추가되는 orderList를 order 클래스 안에 함께 관리하려고 했다. 그러나 만약 추가 주문을 1000000번 한다면 Order은 꽤 많은 메모리 사용량을 갖게 될 것이다. 주문 시 기능을 추가하려고 할 때도 복잡해진다.

그래서 order를 단순 주문만 관리하는 orderItem과 최종 주문을 관리할 order로 나누었다. 

orderItem에서는 메뉴의 price, count, total price, discount여부까지의 단순한 주문 정보를 가져오고 order는 테이블 별 주문서를 모두 모아 메뉴 정보와 최종 가격을 반환한다. 이때 회원정보를 불러와 포인트를 적립하는 등 기능을 추가하기도 쉬워졌다.

 

 

Optional.Empty()와 Null 

Optional.Empty()는 Null과는 다르다. 
Optional.Empty() ? 값이 없음(비어있는 객체) : Null (객체 자체가 null) 

 

그러므로 assertTrue로 값이 없는 객체가 맞니? 해주어야 한다. 

 

 

 

왜 메뉴가 테이블 번호당 하나밖에 들어가지 않을까? Map<테이블번호, OrderItem>로 되어있었다. 

 

Map<테이블번호, List<OrderItem>>에 넣어야 OrderItem의 리스트가 들어가게 된다. 
repository와 service레이어까지 전부 수정했다. ^>^

 

 

 

💡 각 주문서를 하나의 최종주문서로 합치기 

 

[Order의 요구사항]

Order에서는 OrderItem, 그러니까 테이블 당 주문서 여러 개가 있을 수 있다. 그리고 주문서에는 또 여러 개의 주문이 있을 수 있다. 
테이블당 여러 주문서List<OrderItem>의 주문들OrderItem을 합쳐 최종 주문서Order에 넣는 작업이 필요하다. 

 

그러면 지금 계획은 이렇다. 


[첫 번째 시도]


1. OrderItem에서의 주문맵을 테이블 번호로 가져와
2. 주문서의 메뉴 목록을 .stream 하여 메뉴 이름이 같으면 count를 증가
      + finalOrderMap (최종 주문서에 들어갈)을 만들어 넣어준다.
3. 주문서(finalOrderMap)의 단일 메뉴 값 * count 하고 그 메뉴들의 합계를 finalPrice에 넣어준다. 


[실패 ^.^ 한 이유]

Map<테이블번호, List<OrderItem>>에 저장하려 했으나 이 상태에서 finalPrice를 추가하려면 아예 최종 가격을 포함한 Order자체가 value로 들어가야 한다. 

그렇다면 


[두 번째 시도]


1. Map<테이블번호, List<OrderItem>> 를 깐다. 
2. List<OrderItem>을 깐다.
3. OrderItem을 하나씩 돌려서 중복된 메뉴이름의 주문 개수를 모두 더한 값을 새로운 OrderItem에 넣는다 
4. 이걸 새로운 List<OrderItem>에 넣는다 
5. finalPrice를 계산하여 새로운 Order에 3.4에서 만든 값을 넣고 상태를 completed로 바꾼 뒤 (최종 주문서라 계산서라고 볼 수 있음)
6. Map<테이블번호, Order>에 넣어서 반환


 

 

그리고 모든 최종 주문서를 반환할 때 repository에서 Map<Integer, List<OrderIte>>으로 받았기 때문에
또 service레이어에서 모든 주문서를 조회할 때 또 타입 변환을 해주어야 한다 허허 

두근두근 

 

 

 

 

어라....? 어? 

 

 

1=
tableNo.1 [
프랑스식 양 샴꼬, 13000원, 2개, total: 26000원, [CREATED], D: false,
스테이크, 35000원, 1개, total: 35000원, [CREATED], D: true]
/ 최종 합계: 61000원[COMPLETED],

2=
tableNo.2 [
그라탕, 14250원, 2개, total: 30000원, [CREATED], D: true,
크림 소스 파스타, 17100원, 2개, total: 36000원, [CREATED], D: true]
/ 최종 합계: 66000원[COMPLETED],

3=
tableNo.3 [
로스트 치킨, 28000원, 1개, total: 28000원, [CREATED], D: false,
로스트 치킨, 28000원, 1개, total: 28000원, [CREATED], D: false]
/ 최종 합계: 56000원[COMPLETED]}

같은 메뉴를 같은 개수로 같은 테이블에서 동시에 두 번 주문할 경우 합쳐지지 않는다 🥲
 이건 어떻게 처리하면 좋을까...? 

 

728x90