[MVC] 동전 자판기 구현하기

0_0_yoon·2021년 12월 13일
0
post-thumbnail
post-custom-banner

구현하면서 가장 많이 고민했었던 세 가지를 중심으로 써봤다.

📌 유효성 검증은 어디서 할 것인가?

📍 View에서 모든 유효성 검증을 해보자!

최전선에서 입력값을 받아 바로 검증을 하는 게 단순하고 여러 로직을 거칠 필요가 없어 효율적이라고 생각했다. FormatUtil을 만들고 입력값을 도메인 객체 생성에 필요한 값으로 변환하는 메서드를 만들었다. 이를 통해 View에서 유효성 검증을 할 때와 도메인 객체를 생성할 때 중복을 피하고 의도한 대로 View에서 모든 검증을 하고 도메인에서는 예외 발생 코드가 없는 깔끔한 로직 구현을 할 수 있었다. 하지만 예외 케이스가 늘어날 때마다 동시에 View가 점점 커졌다. 그래서 하나의 페이지마다 클래스를 생성해서 나눠봤지만 여러 개의 입력값을 동시에 받는 페이지에서는 의미가 없었다.

📍 도메인 객체들에게 위임할 것인가?

도메인 객체들을 일급컬렉션으로 만들고 원시값을 포장해서 스스로 검증할 수 있도록 만들어보자! View가 굉장히 깔끔해졌다. 동시에 도메인 객체들이,,, 그래도 객체들을 잘 나누면 깔끔하게 될 줄 알았지만 실패.

📍 결국 모두에게 검증 역할을,,

결국 View, 도메인객체에서 모두 검증을 해줬다. 물론 같은 검증은 아니고 따로 양식을 변환할 필요 없는 값들(빈값, 타입체크)은 View에서 해줬고 나머지는 도메인 객체에서 했다.

📌 예외처리는 어디서?

처음 View에서 모든 유효성 검증하려고 했던 이유가 이것 때문이었다. 검증과 동시에 예외 처리를 쉽게 하기 위해서! 하지만 View에서 모든 검증을 하긴 어렵다는 걸 깨닫고 도메인 객체가 던진 예외를 어디서 처리할 것인지 고민하다가 사용자 요청과 컨트롤러를 연결하고 있는 main메서드에서 해줬다.

📌 사용자의 요청과 컨트롤러를 어떻게 연결 시킬 것인가?

처음에는 main 메소드에서 컨트롤러와 뷰를 맵핑 시켜줬는데 길어진 코드를 보면서 main메소드의 역할을 다시 한번 생각해봤다. main메소드는 엔트리 포인트 역할만을 한다고 생각하고 adapter라는 새로운 객체를 만들어 맵핑과 도메인객체에서 던진 예외를 처리하는 역할을 위임했다.
(만약 사용자가 화면을 선택하는 기능이 있다면 선택 입력값과 맵핑해주는 로직을 가지는 열거타입을 만들어 구현하면 깔끔하겠다는 생각이 들었다. 다음에 적용해보기로)

📌 요구사항

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

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

📌 To do list

  • 입력금액에 맞는 동전 랜덤 생성
    • 사용자의 투입 금액으로는 동전을 생성하지 않는다.
  • 자판기가 보유한 동전 보여주기
  • 상품등록
    • 상품명, 가격, 수량으로 상품등록
    • 상품 가격은 100원 부터
    • 10원 단위
  • 금액투입
  • 상품구매
  • 투입금액(잔여금액) 보여주기
  • 잔돈을 동전으로 교환
    • 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 바로 잔돈을 돌려준다.
    • 최소 개수의 동전으로 되돌려준다.
    • 지폐를 잔돈으로 반환하는 경우는 없다.
    • 잔돈을 반환할 수 없는 경우 잔돈으로 반환할 수 있는 금액만 반환한다.
  • 잔돈출력

📍 예외발생 케이스

  • 모든 입력값이 빈값일 경우 예외발생
  • 자판기 금액 입력값은 숫자만 가능하다.
  • 자판기 금액 입력값은 10이상의 숫자만 가능하다.
  • 자판기 금액 입력값은 10의 배수만 가능하다.
  • 상품 등록시 상품당 상품명, 가격, 수량 총 3가지로 이뤄져야한다.
  • 상품 등록시 상품내용은 " [ ", " ] "로 감싸져 있어야 한다.
  • 상품 이름은 한 글자 이상
  • 상품 가격은 숫자
  • 상품 가격은 100원 이상
  • 상품 가격은 10원 단위
  • 상품 수량은 숫자
  • 상품 수량은 1개 이상
  • 상품 구매시 등록된 상품인지 확인
profile
꾸준하게 쌓아가자
post-custom-banner

0개의 댓글