마일리지 상점은 총 5개의 트럭만 이용해 배송한다고 했습니다. 주문을 완료하면 주문한 물품을 싣고 배송을 시작하는 것입니다. 그리고 배송이 끝나면 트럭이 돌아와 배송을 다시 할 수 있습니다.
이렇게 배송에 대한 구조체를 만들기 위해 구체화를 해보겠습니다. 이 택배 트럭의 정보를 가지는 구조체를 만듭니다. 이 구조체는 두 개의 필드 값을 가집니다.
- 배송 상태(string)
- 배송하는 물품(map)
배송 상태는 말 그대로 현재 트럭으로 배송되고있는 물품들의 배송 상태를 나타냅니다. 배송하는 물품은 주문한 물품들의 종류와 수량을 담는 map형으로 저장합니다. 이 구조체를 생성하고 map형 필드값을 위해 생성자도 선언해보시기를 바랍니다.
아래 예시를 확인해보세요.
머릿속으로 프로그램의 흐름이 그려지나요? 지금까지 구현한 코드는 바로 주문이든 장바구니 품목들의 주문이든 아이템들의 수량이 차감되고 사용자의 포인트가 차감되기만 했습니다. 이제는 여기에 추가로 배송을 시작해 배송 상태를 시간의 흐름에 따라 값을 바꿔주고, onedelivery
맵에 배송하는 물품의 이름과 수량을 추가하면 됩니다.
쉽게 이해하기 위해 delivery
구조체 즉, 객체를 트럭 한대라고 생각하라고 했습니다. 5개의 트럭이 필요하니 이 객체를 5개를 생성해야겠죠? 슬라이스를 이용해 5개의 객체를 생성합니다.
이제 deliverylist[i]
객체들은 트럭으로 생각하세요. 트럭을 만들기만 하면 끝이 아닙니다. 트럭은 물품을 싣고 배송을 진행하는 기능을 해야합니다. 이를 우리는 고루틴을 이용해 구현할 것입니다. 각 트럭은 접수된 주문에 따라 비동기적으로 프로세스를 진행합니다. 따라서 트럭의 기능을 각각 부여하기 위해 고루틴을 5개 만듭니다. 이 고루틴이 바로 아까 말한
- 배송 진행
- 물품 싣기
기능을 하게 합니다. 물품을 싣고 배송을 진행하는 함수를 main() 함수 밖에 선언하고 이를 고루틴으로 호출합니다. 저는 이 함수를 deliveryStatus()
라고 만들었습니다. 이를 for문으로 5번 고루틴 호출합니다. 고루틴은 비동기적으로 호출되기 때문에 호출될 때 약간의 딜레이를 주기 위해 time.Sleep()
을 사용합니다.
이제 주문(바로, 장바구니) 기능에 두 가지를 추가하면 됩니다.
- 고루틴에 배송 시작 송신
- 주문한 상품과 수량을
onedelivery
맵에 저장
주문을 하는 함수의 루틴은 모두 main루틴에 있고 수신 루틴은 아까 선언한 go deliveryStatus()
이기 때문에 송/수신에 문제는 없습니다. 우선 주문을 하면 송신으로 배송 시작을 알리고, deliveryStatus
루틴에서 수신하면
주문접수 - 10초 대기 - 배송중 - 30초 대기 - 배송완료 - 10초 대기 - 배송 상태 초기화를 구현해봅니다. 그 후에 물론 numbuy
를 1 감소시켜야합니다.
가장 어려운 부분입니다. 잘 생각해봅니다. 각 트럭은 번호가 붙여져서 각 트럭의 기능을 합니다. 1번 트럭이 5번 트럭의 기능을 하면 안됩니다. 각각의 기능을 수행하기 때문에 고루틴은 총 5개입니다. 그리고 5개의 루틴은 채널 데이터가 송신되기를(택배가 출발하는것을) 기다립니다. 그리고 배송이 완료되면 다시 돌아와 송신하는 것을 무한 반복합니다. 이 5개의 루틴이 각각 이 기능을 수행합니다.
우선 배송의 시작을 알리는 채널을 생성합니다. 이 채널은 bool형으로 주문이 접수되면 true를 송신합니다. 당연히 이 채널을 사용하기 위해 이 채널을 사용하는 함수는 모두 매개변수로 추가해야합니다.