1. 설계 방법 고민하기
•
이번 주차에 tdd를 넣고자 했으나, 코드 리뷰를 하고 이를 정리하는 데에 거의 4일을 쏟아붓는 바람에,,, tdd 책을 다 읽지 못했다. 따라서, tdd는 다음주에 적용하고자 한다. 우선은 지난 주에 익힌 객체지향적인 설계 방식을 한 번 더 적용하며 동시에 코드 리뷰를 통해 배운 것들을 적용하는 데까지를 목표로 잡았다.
2. 이번 과제 정리하기
•
프로그래밍 요구 사항
함수 길이가 15라인 넘지 않게 한다(한 가지 일만 하도록 구현)
else 예약어 쓰지 않는다. switch/case도 쓰지 않는다. (early return은 가능)
enum을 사용한다
도메인 로직에 단위 테스트를 구현한다. 단, UI 로직은 제외한다.
(도메인 로직과 UI 담당 로직 분리해 구현)
Random 값 추출은 pickUniqueNumbersInRange()를 활용한다.
List<Integer> numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);
사용자가 입력하는 값은 readLine()을 활용한다.
제공하는 Lotto 클래스를 활용해 구현해야 한다. (패키지 변경은 가능)
numbers의 접근 제어자인 private을 변경할 수 없다.
Lotto에 필드(인스턴스 변수)를 추가할 수 없다.
public class Lotto {
private final List<Integer> numbers;
public Lotto(List<Integer> numbers) {
validate(numbers);
this.numbers = numbers;
}
private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException();
}
}
// TODO: 추가 기능 구현
}
Java
복사
indent는 2까지만 허용한다
3항 연산자 사용하지 않는다
기능 목록이 정상 동작함을 테스트코드로 확인한다
•
과제 진행 요구 사항
◦
기능 구현 전에 기능 목록 만들고, 기능 목록 단위로 커밋하기
•
과제 목표
◦
클래스(객체)를 분리하는 연습하기
◦
도메인 로직에 대한 단위 테스트를 작성하는 연습하기
•
기능 요구 사항
◦
구입 금액을 입력받는다.
▪
로또 1장의 가격은 1000원
◦
구입 금액만큼 로또를 구입해, 구매한(발행한) 로또의 수량과 번호를 출력한다.
▪
번호는 오름차순 정렬
◦
당첨 번호와 보너스 번호를 입력받는다.
▪
로또 번호는 1~45 사이의 숫자 6개로 이루어지며 중복 안됨
◦
발행한 로또 번호와 당첨 번호를 비교해, 당첨 통계(등수 별 당첨 개수와 수익률)을 출력한다.
▪
수익률은 소수점 둘째 자리에서 반올림
•
예외 처리
◦
사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
◦
(view) 사용자가 입력한 구입 금액이 정수가 아닐 때
◦
(model) 사용자가 입력한 구입 금액이 1000원으로 나누어 떨어지지 않을 때
◦
(view) 사용자가 입력한 당첨 번호가 (쉼표로 구분된) 정수형 리스트가 아닐 때
◦
(view) 사용자가 입력한 보너스 번호가 정수가 아닐 때
◦
(model) 사용자가 입력한 당첨 번호, 보너스 번호가 1~45 사이가 아닐 때
◦
(model) 사용자가 입력한 당첨 번호 개수가 6개가 아닐 때
◦
(model) 사용자가 입력한 당첨 번호가 중복될 때
3. 지난 설계 한 번 더 사용해 검증하기
스토리텔링식으로 설계해 협력/책임/역할 정하기
•
이야기 : 모자장수가 로또를 사고 당첨 결과를 얻음
◦
로또 판매를 시작하는 일요일, 로또 가게에 로또 발행 기계, 판매원, 모자 장수, 로또 당첨 계산 어플이 있음
▪
판매원이 모자 장수에게 “얼마어치 구매할 건가요?” 라고 물어봄
•
모자 장수가 판매원에게 “로또 8000원어치 구매요~”라고 말함
▪
판매원이 “8장 구매”라고 로또 발행 기계에 입력함
•
로또 발행 기계가 판매원에게 로또 8장을 종이에 출력해줌
▪
판매원이 “발행된 로또 가져가세요~ 갖고계셔야 당첨금 받으실 수 있어요~”라고 모자장수에게 말함
•
모자 장수가 발행된 로또 가져가서 소유함
◦
일주일이 지나 로또 판매를 마친 토요일, 로또 발표 현장에 왕, 로또 당첨 계산 어플이 있음
▪
왕이 “이번주 당첨 번호는 1,2,5,26,35,42+17 로 결정!”이라고 로또 당첨 계산 어플에 입력함
•
로또 당첨 계산 어플이 왕의 당첨 번호를 입력받음
◦
다음날 일요일, 모자 장수의 집에 모자 장수, 로또 당첨 계산 어플이 있음
▪
모자 장수가 로또 당첨 계산 어플에 본인의 로또 번호를 입력함
•
로또 당첨 계산 어플이 모자 장수의 로또 번호들을 저장함
▪
모자 장수가 로또 당첨 계산 어플에서 “당첨 통계 계산” 버튼을 클릭함
•
로또 당첨 계산 어플이 당첨 통계를 출력함
•
협력 : 요청과 응답
◦
누군가가 판매원에게 판매를 시작하라고 요청함으로써 로또 판매가 시작됨 (in 로또 가게)
▪
판매원이 모자 장수에게 구매 개수를 말할 것을 요청함
•
모자 장수가 구매 개수를 말함으로써 판매원의 요청에 응답함
▪
판매원이 로또 발행 기계에게 개수만큼 로또를 발행할 것을 요청함
•
로또 발행 기계가 로또를 발행함으로써 판매원의 요청에 응답함
▪
판매원이 모자 장수에게 발행된 로또를 가져가서 소유하라고 요청함
•
모자 장수가 발행된 로또 소유함으로써 판매원의 요청에 응답함
◦
누군가가 왕에게 로또 발표를 시작하라고 요청함으로써 로또 당첨 번호 결정이 시작됨 (in 로또 발표 현장)
▪
왕이 로또 당첨 계산 어플에게 결정한 당첨 번호를 저장할 것을 요청함
•
로또 당첨 계산 어플이 당첨 번호를 저장함으로써 왕의 요청에 응답함
◦
누군가가 모자 장수에게 당첨 결과 확인해보라고 요청함으로써 로또 결과 확인이 시작됨 (in 모자 장수의 집)
▪
모자 장수가 로또 당첨 계산 어플에게 본인의 로또 번호를 저장할 것을 요청함
•
로또 당첨 계산 어플이 모자 장수의 로또 번호들을 저장함으로써 모자 장수의 요청에 응답함
▪
모자 장수가 로또 당첨 계산 어플에게 당첨 통계를 계산할 것을 요청함
•
로또 당첨 계산 어플이 당첨 통계를 계산해 출력함으로써 모자 장수의 요청에 응답함
•
책임 : 하는 것(요청, 계산)과 아는 것
◦
판매원
▪
하는 것 : 모자 장수에게 구매할 로또 개수 말하도록 요청, 로또 발행 기계에게 로또 발행하도록 요청, 모자 장수에게 발행한 로또 가져가서 소유할 것을 요청
◦
로또 발행 기계
▪
하는 것 : 로또 번호를 자동으로 뽑아 로또 발행(생성)
◦
모자 장수
▪
하는 것 : 로또 당첨 계산 어플에게 로또 번호들 저장하도록 요청, 로또 당첨 계산 어플에게 당첨 통계 계산하도록 요청
▪
아는 것 : 구매할 로또 개수, 발행된 로또
◦
왕
▪
하는 것 : 로또 당첨 계산 어플에게 당첨 번호 저장하도록 요청
▪
아는 것 : 당첨 번호
◦
로또 당첨 계산 어플
▪
하는 것 : 모자 장수가 구매한 로또들과 당첨 번호 비교해 당첨 규칙대로 당첨 통계를 계산
▪
아는 것 : 모자 장수의 로또, 당첨 번호, 당첨 규칙
•
역할 : 책임의 집합 (재사용성)
◦
판매원 → 로또 판매자 (LottoSeller)
◦
모자 장수 → 로또 구매자 (LottoBuyer)
◦
로또 발행 기계 → 로또 발행기 (LottoGenerator)
▪
로또 (Lotto)
◦
왕 + 로또 당첨 계산 어플 → 로또 당첨 결과 분석기 (LottoWinningAnalyzer)
▪
당첨 번호 (WinningNumbers)
▪
당첨 규칙 (WinningRule)
Today in 프리코스
TIL 작성하기
몰입
이번주에 적용해 볼 설계 방법 고민하기
설계 구상하기 (객체지향적으로 생각해보기)
Search