[자기개발] 택배 배달 프로토타입

iqpizza6349·2022년 9월 21일
0

자기개발

목록 보기
2/3
post-thumbnail

자기개발 택배 배달 과제

다음 내용은 제가 과제를 읽고, 세세하게 작성되지 않은 내용들을 임의로 설계하여 구체한 내용입니다. (고객에 관한 자세한 내용이 없어, 제외하고 설계하였습니다.)
고객이 상품을 주문하면, 해당 상품 재고가 충분한지 여부를 묻는다.
만일 재고가 충분하다 -> 상품 준비 중
만일 재고가 부족하다 -> 상품을 가져온다 > 상품 재고 없음
이때, 재고가 부족하다고 예외를 발생하거나, 못한다고 하는 게 아닌 상품에 재고가 없다고 알린 후,
해당 물품이 들어올 때까지 대기해야한다.

상품이 준비 중 혹은 재고품이 없는 상태라면, 언제든 고객은 취소를 할 수 있다.
상품이 이미 존재한다면, 약 1일(10초) 후, 배송 준비 중 상태로 변한 후
배송 중 상태로 만들어 배송 중임을 알린다.
재고품이 없다면, 약 3일(30초) 후, 상품 준비 중으로 상태를 바꾼다.

배송 중 상태에서 약 2일(20초) 후, 상품은 도착한다.
고객은 물품을 확인 후, 배송 완료하면 주문은 배송 완료 상태가 된다.

이를 아주 간단하게 접근하고자, 순수 자바 코드로 간단하게나마 구현하였다.
(물론, 시간이 소요되어야하는 부분은 제외되었다.)

public class OrderService {

    private final OrderDAO orderDAO = new OrderDAO();
    private final ItemDAO itemDAO = new ItemDAO();

    public Order orderRegistration(String customer, String item, String address) {
        int countOfItem = itemDAO.countByName(item);
        if (countOfItem == 0) {
            requiredStock(item); 
            return orderDAO.save(new Order(1L, customer, item, address, OrderState.NO_STOCK));
        }

        return orderDAO.save(new Order(1L, customer, item, address));
    }

    private void requiredStock(String item) {
        try {
            System.out.println("재고가 없어서 기다리는 중");
            Thread.sleep(1000);
        } catch (InterruptedException ignored) {}
    }
}

Order 클래스는 주문 그자체를 의미하고, Item 클래스는 재고를 의미한다.
각각의 DAO들은 HashMap을 사용하여 데이터베이스를 흉내내고 있는 클래스이다.

위 서비스를 간단하게 테스트하도록 하였다.

public class Test {

    private final ItemDAO itemDAO = new ItemDAO();
    private final OrderService orderService = new OrderService();
    private final OrderDAO orderDAO = new OrderDAO();

    private Order order() {
        return new Order(null, "customer", "item", "address");
    }

    private Order order(OrderState orderState) {
        return new Order(null, "customer", "item", "address", orderState);
    }

    // 상품 주문 - 최초 상태는 상품 준비 중이다.
    public void orderWhenStockIsEnough() {
        // given
        itemDAO.save(new Item(null, "item1"));
        String customer = "customer1";
        String item = "item1";
        String address = "address1";

        // when
        Order order = orderService.orderRegistration(customer, item, address);

        // then
        isNotNull(order);
        isEqual(order.getOrdered(), customer);
        isEqual(order.getItem(), item);
        isEqual(order.getAddress(), address);
        isEqual(order.getOrderState(), OrderState.PRODUCT_PREPARE);
    }

    // 상품 주문 - 재고가 부족할 때
    public void orderWhenStockIsNotEnough() {
        String customer = "customer";
        String item = "item";
        String address = "address";

        // when
        Order order = orderService.orderRegistration(customer, item, address);

        // then
        isNotNull(order);
        isEqual(order.getOrdered(), customer);
        isEqual(order.getItem(), item);
        isEqual(order.getAddress(), address);
        isEqual(order.getOrderState(), OrderState.NO_STOCK);
    }

    // 배송 준비 중
    public void prepareToShip() {
        Order order = orderDAO.save(order());

        order.setOrderState(OrderState.DELIVERY_PREPARE);

        isEqual(order.getOrderState() == OrderState.DELIVERY_PREPARE, true);
    }

    public void shipping() {
        Order order = orderDAO.save(order());

        order.setOrderState(OrderState.SHIPPING);

        isEqual(order.getOrderState() == OrderState.SHIPPING, true);
    }

    public void cancelTest() {
        Order order = orderDAO.save(order());

        order.cancel();

        isEqual(order.getOrderState() == OrderState.CANCELED, true);
    }

    public void shippingCancel() throws Exception {
        Order order = orderDAO.save(order(OrderState.SHIPPING));

        try {
            order.cancel();         // might be exception
        } catch (RuntimeException e) {
            throw new Exception(e);
        }
    }

    public void confirmationTest() {
        Order order = orderDAO.save(order(OrderState.DELIVERY_COMPLETE));

        order.confirmation();
    }

    public void confirmationWhenNotArrived() throws Exception {
        Order order = orderDAO.save(order(OrderState.SHIPPING));

        try {
            order.confirmation();   // might be exception
        } catch (RuntimeException e) {
            throw new Exception(e);
        }
    }

    public void isEqual(Object a, Object b) {
        if (!a.equals(b)) throw new RuntimeException();
    }

    public void isNotNull(Object a) {
        if (a == null) throw new RuntimeException();
    }

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        test.orderWhenStockIsEnough();
        test.orderWhenStockIsNotEnough();
        test.prepareToShip();
        test.shipping();
        test.cancelTest();
        test.shippingCancel();
        test.confirmationTest();
        test.confirmationWhenNotArrived();
    }
}

실제 API로 만들 때, 로직상으로 문제가 존재하는 지 여부를 간단하게 묻고자 테스트를 진행하였다. 순수 자바로 구현함에 있어 무리가 있어보이는 작업들은 (간단하게 구현하기에 무리가 있어보이는) 다음과 같다.

  • 재고품이 부족하다면, 어떻게 서로 요청하고 요청을 받을 것인가?
  • 요청의 상태를 특정 시간마다 어떻게 수정할 것인가?

해당 문제를 다음 포스팅 때는 해결할 수 있길 바란다.

과제를 무사히 끝낼 수 있길 바란다.

profile
coffee.drinkUntilEmpty();

0개의 댓글