/precourse-study-vending-machine

우테코 5기 최종테스트 준비를 위한 이전 미션 풀이 - 2주차

Primary LanguageKotlinMIT LicenseMIT

미션 - 자판기

🔍 진행방식

  • 미션은 기능 요구사항, 프로그래밍 요구사항, 과제 진행 요구사항 세 가지로 구성되어 있다.
  • 세 개의 요구사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다.
  • 기능 요구사항에 기재되지 않은 내용은 스스로 판단하여 구현한다.

✉️ 미션 제출 방법

  • 기존 제출 방법과 같이 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다.
    • Pull-Request 까지만 진행하면 된다.

🚀 기능 요구사항

반환되는 동전이 최소한이 되는 자판기를 구현한다.

  • 자판기가 보유하고 있는 금액으로 동전을 무작위로 생성한다.
    • 투입 금액으로는 동전을 생성하지 않는다.
  • 잔돈을 돌려줄 때 현재 보유한 최소 개수의 동전으로 잔돈을 돌려준다.
  • 지폐를 잔돈으로 반환하는 경우는 없다고 가정한다.
  • 상품명, 가격, 수량을 입력하여 상품을 추가할 수 있다.
    • 상품 가격은 100원부터 시작하며, 10원으로 나누어떨어져야 한다.
  • 사용자가 투입한 금액으로 상품을 구매할 수 있다.
  • 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 바로 잔돈을 돌려준다.
  • 잔돈을 반환할 수 없는 경우 잔돈으로 반환할 수 있는 금액만 반환한다.
    • 반환되지 않은 금액은 자판기에 남는다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
    • Exception이 아닌 IllegalArgumentException, IllegalStateException 등과 같은 명확한 유형을 처리한다.
  • 아래의 프로그래밍 실행 결과 예시와 동일하게 입력과 출력이 이루어져야 한다.

✍🏻 입출력 요구사항

⌨️ 입력

  • 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다.
[콜라,1500,20];[사이다,1000,10]

🖥 출력

  • 자판기가 보유한 동전
500원 - 0개
100원 - 4개
50원 - 1개
10원 - 0개
  • 잔돈은 반환된 동전만 출력한다.
100원 - 4개
50원 - 1개
  • 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 [ERROR]로 시작해야 한다.
[ERROR] 금액은 숫자여야 합니다.

💻 프로그래밍 실행 결과 예시

자판기가 보유하고 있는 금액을 입력해 주세요.
450

자판기가 보유한 동전
500원 - 0개
100원 - 4개
50원 - 1개
10원 - 0개

상품명과 가격, 수량을 입력해 주세요.
[콜라,1500,20];[사이다,1000,10]

투입 금액을 입력해 주세요.
3000

투입 금액: 3000원
구매할 상품명을 입력해 주세요.
콜라

투입 금액: 1500원
구매할 상품명을 입력해 주세요.
사이다

투입 금액: 500원
잔돈
100원 - 4개
50원 - 1개

🎱 프로그래밍 요구사항

  • Kotlin 1.6.20에서 실행 가능해야 한다. Kotlin 1.6.20에서 정상적으로 동작하지 않을 경우 0점 처리한다.
  • Java 코드가 아닌 Kotlin 코드로만 구현해야 한다.
  • 프로그램 실행의 시작점은 Applicationmain()이다.
  • build.gradle(.kts)을 변경할 수 없고, 외부 라이브러리를 사용하지 않는다.
  • Kotlin 코드 컨벤션 가이드를 준수하며 프로그래밍한다.
  • 프로그램 종료 시 System.exit()를 호출하지 않는다.
  • 프로그램 구현이 완료되면 ApplicationTest의 모든 테스트가 성공해야 한다. 테스트가 실패할 경우 0점 처리한다.
  • 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 이름을 수정하거나 이동하지 않는다.
  • indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
    • 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
    • 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
  • 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
  • JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.
  • else를 지양한다.
    • 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
    • 때로는 if/else, when문을 사용하는 것이 더 깔끔해 보일 수 있다. 어느 경우에 쓰는 것이 적절할지 스스로 고민해 본다.
  • 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(println, readLine 등) 로직은 제외한다.
    • 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다.
  • 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다.
    • 함수(또는 메서드)가 한 가지 일만 잘하도록 구현한다.
  • 메서드의 파라미터 개수는 최대 3개까지만 허용한다.

성록, 상현의 요구사항

  • 도메인에 대한 단위테스트를 먼저 작성 한후 프로그램을 구현한다.(TDD)
  • 커밋 전에 IDE의 코드 자동 정렬 기능을 활용한다. (중요)
    • IntelliJ IDEA: mac - ⌥⌘L, windows - Ctrl+Alt+L
  • Domain과 View로 나누어 서로의 역할을 침범하지 않게 한다.
    • Domain은 도메인의 역할만 할뿐 사용자에게 표시해주는 역할을 하지 않는다.
  • Boolean 타입을 리턴하는 경우 if문을 쓰지않고 return 다음 조건문만 사용한다.
    • 예: return (a > b)
    • a가 b보다 크다면 true를 리턴 아니라면 false를 리턴
  • 문자열 연산이 많을 때는 StringBuilder 를 사용하도록 한다.
    • 때로는 $ 나 + 연산자를 사용하는 것이 더 깔끔해 보일 수 있다. 어느 경우에 쓰는 것이 적절한지 스스로 고민해 본다.

프로그래밍 요구사항 - Coin

  • Coin enum class를 활용해 구현해야 한다.
  • 필드(인스턴스 변수)인 amount의 접근 제어자 private을 변경할 수 없다.
enum class Coin(private val amount: Int) {
  COIN_500(500),
  COIN_100(100),
  COIN_50(50),
  COIN_10(10);

  // 추가 기능 구현
}

프로그래밍 요구사항 - Randoms, Console

  • camp.nextstep.edu.missionutils에서 제공하는 Randoms, Console API를 활용해 구현해야 한다.
    • Random 값 추출은 camp.nextstep.edu.missionutils.RandomspickNumberInList()를 활용한다.
    • 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.ConsolereadLine()을 활용한다.

📈 과제 진행 요구사항

  • 미션은 precourse-study-vending-machine 저장소를 Fork & Clone해 시작한다.
  • 기능을 구현하기 전 docs/README.md에 구현할 기능 목록을 정리해 추가한다.
  • Git의 커밋 단위는 앞 단계에서 docs/README.md에 정리한 기능 목록 단위로 추가한다.
  • 과제 진행 및 제출 방법은 프리코스 과제 제출 문서를 참고한다.
  • 과제의 원본을 확인하고 싶으면 여기에서 확인한다.