Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

2주차 미션 - 자동차 경주

🤔 1주차 회고

  • 2주차의 목표는 readMe 깔끔하게 작성하기, 주석 적게 사용하기, 일급 컬렉션 사용하기, MVC 패턴 적용하기였다.

  • 악취가 났던 1주차와는 달리, 만족할만한 퀄리티가 나왔다. 새 집으로 이사한 느낌도 들었다.

  • 3주차의 3번째 프로그래밍 요구 사항인 15라인 넘어가지 않기else 예약어를 쓰지 않기도 벌써 달성해냈다!

    controller의 run() 메서드는 15라인을 넘어버렸는데, 어떻게 해결해야 할지 고민해봐야겠다.🤔

    이븐하게 익었어요

  • 이번엔 이븐하게 익었어요


  • 아쉬운 점으로는 테스트를 적극적으로 활용하지 않았다는 점이었다.

😠 3주차 목표

  • 테스트 도구를 적극 활용하기(다양한 테스트 메서드 활용)
  • 단위 테스트만으로 모든 메서드에 대해 커버리지 100% 달성하기
    • 단위 테스트 후 통합 테스트 작성하기
  • ReadMe에 주요 메서드의 기능을 정리하기

🤓 2주차 공통 피드백 - 내가 지키지 못한 것

  • 변수 이름에 자료형은 사용하지 않는다

    변수명에 대한 고민을 조금 더 해보기..

  • 테스트를 작성하는 이유에 대해 본인의 경험을 토대로 정리해본다

    가장 난이도가 높은 문제라고 생각한다. '아! 이거 때문이지!' 하면서도 다시 테스트에 회의감이 들어버리는 상황이 발생한다..

🔍 프로그래밍 요구사항

  • 메서드의 길이가 15라인을 넘어가지 않도록, 한 가지 일만 하도록 구현한다.
  • else, switch/case 를 사용하지 않는다.
  • Enum을 사용한다.
  • UI 로직을 제외한 구현 기능에 대해 단위 테스트를 작성한다.

✔️ 기능 요구사항

  • 랜덤으로 로또를 뽑고 당첨 내역 및 수익률을 확인할 수 있는 로또 발매기
    • 사용자는 로또 구입 금액을 입력 받는다.
      • 구입 금액은 1000원 단위 이다.
    • 금액만큼 로또를 발행한다.
      • 1장 당 1000원이다.
      • 랜덤값을 뽑을 때는 pickUniqueNumbersInRange() 를 활용한다.
        // 1에서 45 사이의 중복되지 않은 정수 6개 반환
        Randoms.pickUniqueNumbersInRange(1, 45, 6);
        
      • 로또 번호는 오름차순 정렬한다.
    • 당첨 번호 6개와 보너스 번호 1개를 뽑는다.
      • 번호는 중복되지 않는다.
      • 당첨 번호는 쉼표(,)를 기준으로 구분한다.
    • 로또 번호와 당첨 번호를 비교한다.
      • 당첨 내역 및 수익률을 출력한다.
      • 수익률은 소수점 둘째 자리에서 반올림한다.
      당첨 기준과 금액
      1등: 6개 번호 일치 / 2,000,000,000원
      2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원
      3등: 5개 번호 일치 / 1,500,000원
      4등: 4개 번호 일치 / 50,000원
      5등: 3개 번호 일치 / 5,000원
      
    • 예외 상황 시 에러 문구를 출력해야 한다.
      • 에러 문구는 [ERROR] 로 시작해야 한다.
      • 잘못된 값을 입력한 경우 IllegalArgumentException 을 발생시킨다.
      • 명확한 에러 유형을 처리한다.

📜 기능명세서

로또 구입 금액 입력

  • 로또 구입 금액을 입력 받는다.
  • 1000원으로 나누어 떨어지지 않는지 검증한다.
  • 처리 가능 범위를 넘어서는 금액인 경우인지 검증한다.
  • 잘못된 값을 입력한 경우 에러 메시지를 출력하고 재입력 받는다.
  • 입력받은 로또 구입 금액을 저장한다.

당첨 번호, 보너스 번호 입력

  • 당첨 번호를 입력 받는다.
  • 쉼표, 숫자 외의 문자가 있는지 검증한다.
  • 쉼표가 잘못 위치한 경우를 검증한다.
  • 보너스 번호를 입력 받는다.
  • 숫자가 1~45에 속하는지 검증한다.
  • 입력받은 당첨 번호를 저장한다.
  • 입력받은 보너스 번호를 저장한다.

사용자 입력은 camp.nextstep.edu.missionutils.ConsolereadLine()을 활용한다.

로또 발행

  • 로또 구입 금액으로부터 구입 가능한 로또 개수를 구한다.
  • 로또를 발행한다.

    랜덤값을 뽑을 때는 pickUniqueNumbersInRange() 를 활용한다.

  • 발행한 로또 정보를 출력한다.

당첨 확인

  • 발행한 로또들의 당첨 여부를 확인한다.
  • 당첨 통계를 출력한다.
  • 총 수익률을 출력한다.

예외 처리

  • 명확한 유형을 지정하여 각 예외를 처리한다.

🎫 주요 메서드 기능

PurchaseAmountService

  • 입력값으로 받은 구매금액을 처리하는 클래스입니다.
메서드 명 설명
save 로또 구매금액 입력값을 받아 검증, 파싱, 저장을 수행합니다.

WinnerNumberService

  • 입력값으로 받은 당첨번호를 처리하는 클래스입니다.
메서드 명 설명
save 당첨번호 입력값을 받아 검증, 파싱, 저장을 수행합니다.

BonusNumberService

  • 입력값으로 받은 보너스번호를 처리하는 클래스입니다.
메서드 명 설명
save 보너스번호 입력값을 받아 검증, 파싱, 저장을 수행합니다.

LotteryMachineService

  • 로또 발매기의 동작을 제어하는 객체로서, 입력 금액으로 로또를 발행하고, 당첨 여부를 조회하고, 결과를 전달합니다.
메서드 명 설명
buy 저장된 구매금액만큼 로또를 발행합니다.
getPurchaseCount 구매금액으로 발행 가능한 로또 개수를 반환합니다.
issue 로또 개수만큼 발행하고 로또 발매기에 저장합니다.
generate 랜덤한 번호로 로또를 발행합니다.
check 저장된 당첨번호, 보너스 번호, 발행된 로또를 조회하여 당첨 여부를 확인합니다.
compare 당첨번호 개수, 보너스 번호 맞춤 여부를 확인하여 그에 맞는 상품 통계를 저장합니다.
savePrize 당첨번호 개수, 보너스 번호 맞춤 여부에 맞는 상품을 조회하여 통계에 저장합니다.
getStatistic 통계 정보를 조회합니다.
appendResult 각 상품에 대한 통계 정보를 조회합니다.
getProfitRate 수익률 정보를 조회합니다.
computeProfitRate 수익률을 계산합니다.

LotteryMachineModel

  • 현실의 발매기와 대응되는 객체로서, 발매에 필요한 데이터들을 저장하고 조회합니다.
메서드 명 설명
insertPurchaseAmount 구매금액을 저장합니다.(돈을 투입합니다.)
settingWinnerNumber 당첨번호를 저장합니다.(새로운 회차의 당첨번호를 뽑습니다.)
settingBonusNumber 보너스번호를 저장합니다.(새로운 회차의 보너스번호를 뽑습니다.)
settingIssuedLotto 발행된 로또를 저장합니다.(사용자의 로또 발행 번호를 저장합니다.)
consumePurchaseAmount 구매금액을 조회하면서 0원으로 초기화합니다.

StatisticModel

  • 발매기의 책임을 분리하여 통계 정보를 저장하는 객체입니다. 통계 데이터를 저장하고 조회합니다.
메서드 명 설명
add 인자로 받은 상품에 대해 개수를 1 증가시킵니다.

👀 제출 전 과제에 대한 한 줄 평

  • 이번 과제 목표 달성 여부
  • 테스트 도구를 적극 활용하기(다양한 테스트 메서드 활용)
    • ParameterizedTest를 익히고 완벽하게 활용해냈습니다.
    • NsTest 메서드도 적극 활용하여 통합 테스트의 여러 케이스를 검증했습니다.
  • 단위 테스트만으로 모든 메서드에 대해 커버리지 100% 달성하기
    • 출력, 검증, 컨트롤러, 상수를 제외한 모든 메서드에 대해 커버리지를 100% 달성했습니다.
    • 통합 테스트를 통해 상수를 제외한 모든 메서드에 대해서도 커버리지를 100% 달성했습니다.
  • ReadMe에 주요 메서드의 기능을 정리하기
    • 주요 메서드에 대한 클래스 정의서를 작성했습니다.

의존성 주입 객체

  • 여러 컨트롤러들을 만들면서 동일한 모듈을 사용하기 위해 외부에서 주입이 필요했고, 이를 위해 의존성 주입 컨테이너 ObjectFactory를 만들었습니다.
  • 덕분에 클라이언트는 컨트롤러들의 세부 모듈을 알 필요 없이 호출할 수 있게 되었습니다.

중복되는 검증 메서드

  • 여러 엔티티로 나누면서 중복되는 검증 메서드들이 생겨났습니다. 중복을 제거하기 위해 여러 방법을 고민했지만, 다음 이유들로 인해 적용하지 않았습니다.
    • 상속 : 결합도가 강해져 확장이 어려워집니다.
    • 유틸 클래스 : 엔티티의 책임을 외부 모듈로 분리하지 않고, 한 곳에 몰아넣어 응집도를 높이고 싶었습니다.

테스트 고도화

  • 기존 테스트를 작성했을 때에는 다중 조건의 커버리지를 위해 비슷한 테스트 케이스가 여러 개 생겨났습니다.
  • 하지만 @ParameterizedTest 를 학습하고 적용하면서, 중복되는 케이스들이 제거되었고 가독성이 향상되었습니다.

TDD 미도입

  • TDD는 가성비 측면에서 적합하지 않다고 생각하여 적용하지 않기로 했습니다.
  • 실제 프로젝트에서 시간은 넉넉하지 않고, 기획은 계속 변경되어 로직의 의도 자체가 바뀌는 경우가 잦았습니다.
  • 프리코스에서도 마찬가지로 요구사항을 한 번에 이해하기 힘들고, 중간에 깨우쳐 로직이 바뀌는 부분이 존재하기 때문에 TDD는 가성비가 좋지 않다고 판단하였습니다.

About

우테코 3주차 - 로또

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages