본문 바로가기

우테코

우테코 4주차 - [크리스마스 이벤트] 프로그래밍 요구사항 및 기능목록 작성

이번 4주차는 그동안 우테코에서 출제되지 않은 문제가 나온 만큼

온라인 상에서 어떤 소스도 참고하지 않고 오로지 본인의 실력만으로 승부해야 하는 문제였다.

 

특히, 요구조건이 상당히 많기에 그 조건을 잘 정리해두고

하나하나 정교하게 완성해나아가는 과정이 굉장히 중요했다.

 

그럼 우테코 미션의 마지막을 장식할 4주차 미션의

요구사항과 기능구현 목록을 정리해보자

 


먼저 이벤트 대상인 메뉴는 다음과 같다.

<애피타이저> 양송이수프(6,000), 타파스(5,500), 시저샐러드(8,000)
<메인> 티본스테이크(55,000), 바비큐립(54,000), 해산물파스타(35,000), 크리스마스파스타(25,000)
<디저트> 초코케이크(15,000), 아이스크림(5,000)
<음료> 제로콜라(3,000), 레드와인(60,000), 샴페인(25,000)

 

 

이벤트의 종류는 다음과 같다.

크리스마스 디데이 할인
    - 이벤트 기간: 2023.12.1 ~ 2023.12.25
    - 1,000원으로 시작하여 크리스마스가 다가올수록 날마다 할인 금액이 100원씩 증가
    - 총주문 금액에서 해당 금액만큼 할인  
      (e.g. 시작일인 12월 1일에 1,000원, 2일에 1,100원, ..., 25일엔 3,400원 할인)
- 평일 할인(일요일~목요일): 평일에는 디저트 메뉴를 메뉴 1개당 2,023원 할인
- 주말 할인(금요일, 토요일): 주말에는 메인 메뉴를 메뉴 1개당 2,023원 할인
- 특별 할인: 이벤트 달력에 별이 있으면 총주문 금액에서 1,000원 할인
- 증정 이벤트: 할인 전 총주문 금액이 12만 원 이상일 때, 샴페인 1개 증정
- 이벤트 기간: '크리스마스 디데이 할인'을 제외한 다른 이벤트는 2023.12.1 ~ 2023.12.31 동안 적용

 

# 혜택 금액에 따른 이벤트 부여

여기서 주의해야 할 점은 만약 샴페인을 증정받았다면 샴페인의 가격인 25000원이 혜택금액에 더해진다는 사실이다.

- 총혜택 금액에 따라 다른 이벤트 배지를 부여합니다. 이 배지는 2024 새해 이벤트에서 활용할 예정입니다.
  배지에 따라 새해 이벤트 참여 시, 각각 다른 새해 선물을 증정할 예정입니다.
    - 5천 원 이상: 별
    - 1만 원 이상: 트리
    - 2만 원 이상: 산타

 

# 이벤트 주의사항

- 총주문 금액 10,000원 이상부터 이벤트가 적용됩니다.
- 음료만 주문 시, 주문할 수 없습니다.
- 메뉴는 한 번에 최대 20개까지만 주문할 수 있습니다.  
  (e.g. 시저샐러드-1, 티본스테이크-1, 크리스마스파스타-1, 제로콜라-3, 아이스크림-1의 총개수는 7개)

 

#예외사항 처리방식

 

- 날짜

= 1-31 이하의 숫자가 아닌 경우 : [ERROR] 유효하지 않은 날짜입니다. 다시 입력해 주세요.

 

- 메뉴와 개수 (e.g 해산물 파스타-2, 레드와인-1, 초코케이크-1)

= 메뉴판에 없는 메뉴 

= 메뉴의 개수가 1이상의 숫자가 아닐때

= 메뉴 형식이 다를 때

= 중복메뉴를 입력했을 때 (e.g : 시저샐러드-1, 시저샐러드-1)

=>  : [ERROR] 유효하지 않은 주문입니다. 다시 입력해 주세요.

 

#입출력 예시

안녕하세요! 우테코 식당 12월 이벤트 플래너입니다.
12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)
26 
주문하실 메뉴를 메뉴와 개수를 알려 주세요. (e.g. 해산물파스타-2,레드와인-1,초코케이크-1)
타파스-1,제로콜라-1 
12월 26일에 우테코 식당에서 받을 이벤트 혜택 미리 보기!
 
<주문 메뉴>
타파스 1개
제로콜라 1개

<할인 전 총주문 금액>
8,500원
 
<증정 메뉴>
없음
 
<혜택 내역>
없음
 
<총혜택 금액>
0원
 
<할인 후 예상 결제 금액>
8,500원
 
<12월 이벤트 배지>
없음
```
안녕하세요! 우테코 식당 12월 이벤트 플래너입니다.
12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)
3
주문하실 메뉴를 메뉴와 개수를 알려 주세요. (e.g. 해산물파스타-2,레드와인-1,초코케이크-1)
티본스테이크-1,바비큐립-1,초코케이크-2,제로콜라-1
12월 3일에 우테코 식당에서 받을 이벤트 혜택 미리 보기!
 
<주문 메뉴>
티본스테이크 1개
바비큐립 1개
초코케이크 2개
제로콜라 1개
 
<할인 전 총주문 금액>
142,000원
 
<증정 메뉴>
샴페인 1개
 
<혜택 내역>
크리스마스 디데이 할인: -1,200원
평일 할인: -4,046원
특별 할인: -1,000원
증정 이벤트: -25,000원
 
<총혜택 금액>
-31,246원
 
<할인 후 예상 결제 금액>
135,754원
 
<12월 이벤트 배지>
산타

 

프로그램 설명은 여기서 끝이지만

프로그래밍 요구사항은 아직 끝이 아니다.

 

우선 기존 프로그래밍 요구사항을 그대로 상속받으며

- JDK 17 버전에서 실행 가능해야 한다. **JDK 17에서 정상적으로 동작하지 않을 경우 0점 처리한다.**
- 프로그램 실행의 시작점은 `Application`의 `main()`이다.
- `build.gradle` 파일을 변경할 수 없고, 외부 라이브러리를 사용하지 않는다.
- [Java 코드 컨벤션](https://github.com/woowacourse/woowacourse-docs/tree/master/styleguide/java) 가이드를 준수하며 프로그래밍한다.
- 프로그램 종료 시 `System.exit()`를 호출하지 않는다.
- 프로그램 구현이 완료되면 `ApplicationTest`의 모든 테스트가 성공해야 한다. **테스트가 실패할 경우 0점 처리한다.**
- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 이름을 수정하거나 이동하지 않는다.
- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
    - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
    - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- 3항 연산자를 쓰지 않는다.
- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
    - 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
- JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.
- else 예약어를 쓰지 않는다.
    - 힌트: if 조건절에서 값을 return 하는 방식으로 구현하면 else를 사용하지 않아도 된다.
    - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.
- 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다.
    - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다.
- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
    - `Exception`이 아닌 `IllegalArgumentException`, `IllegalStateException` 등과 같은 명확한 유형을 처리한다.

 

=> 추가된 요구사항은 다음과 같다

 아래 있는 `InputView`, `OutputView` 클래스를 참고하여 입출력 클래스를 구현한다.
    - 입력과 출력을 담당하는 클래스를 별도로 구현한다.
    - 해당 클래스의 패키지, 클래스명, 메서드의 반환 타입과 시그니처는 자유롭게 구현할 수 있다.
  public class InputView {
      public int readDate() {
          System.out.println("12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)");
          String input = Console.readLine();    
          // ...
      }
      // ...
  ```java
  public class OutputView {
      public void printMenu() {
          System.out.println("<주문 메뉴>");
          // ...
      }
      // ...
  }

 

=> 결국 지난 주의 요구사항은 Controller와 주요 로직을 분리시키는 일이었고

=> 이번 주의 요구사항은 View 의 분리에 더 신경을 써야하는 느낌이었다.

 

지난 4주의 시간을 통해

결국 MVC 모델의 설계패턴을 학습하는 것이

우테코의 궁극적인 목표라는 점을 알게 되었다.

 


이에 따라 기능구현목록을 작성해 보았다.

 

# 기능 구현 목록
- [0] 방문 날짜 입력받기
    -[0] 1-31사이의 날짜를 입력받는다.
    -[] 입력받은 날짜의 요일을 파악한다.
    -[0] 유효하지 않은 날짜의 경우 오류 메시지 출력

- [0] 메뉴와 개수 입력받기
  - [0] 주문한 메뉴와 개수를 입력받는다.
  - [0] 주문한 메뉴가 메뉴판에 있는 메뉴인지 확인한다.
  - [0] 주문한 메뉴의 카테고리를 파악한다.
  - [0] 메뉴판에 없는 메뉴를 주문한 경우 - 오류 메시지 : "[ERROR] 유효하지 않은 주문입니다. 다시 입력해 주세요."
  - [0] 메뉴의 개수가 1이상의 숫자가 아닌 경우 - 오류 메시지 : "[ERROR] 유효하지 않은 주문입니다. 다시 입력해 주세요."
  - [0] 중복 메뉴를 입력한 경우 - 오류 메시지 : "[ERROR] 유효하지 않은 주문입니다. 다시 입력해 주세요."

- [0] 총 주문 금액을 계산한다.
  -[0] 메뉴의 개수가 20개를 넘었는지 확인한다.
        - 넘었다면 할인이 적용되지 않는다. 
  -[0] 총 주문금액이 10,000원을 넘었는지 확인한다.
        - 넘지 않았다면 할인이 적용되지 않는다.   
  -[0] 음료 이외의 카테고리에 주문이 들어왔는지 확인한다.
        - 음료만 주문했다면 할인이 적용되지 않는다.
  -[0] 증정 이벤트 적용여부를 확인한다. 

- [0] 날짜에 따라 할인금액을 계산한다.
  - [0] 크리스마스 디데이 이벤트에 속하는지 확인하고 할인금액을 계산한다.
  - [0] 날짜에 따른 타 이벤트 여부에 속하는지 확인하고 할인금액을 계산한다.
  - [0] 총 할인금액에 따른 뱃지 증정 여부를 확인한다.

-[0] 주문메뉴, 총주문금액, 증정메뉴, 혜택내역, 총혜택금액, 예상결제 금액, 배지 내용을 출력한다.