- 요구사항 분석을 철저히 진행하여 작은 단위로 기능을 나누고, 그에 따라 객체를 설계
- 사이드 이펙트를 발생시킬 수 있는 클래스 내 멤버변수 선언을 지양하고, 메서드로 질의할 수 있도록 설계
- 주석 없이도 팀원이 알 수 있는 명확한 메서드명을 짓기
- get()으로 값을 꺼내서 변경하는 방식의 설계 지양
- Enum 클래스를 사용하여 많은 상수 값을 관리
- 넘겨받은 파라미터 값을 바꾸는 것은 안티패턴으로, 사용을 지양
- 스트랭글러 패턴을 통한 기존 로직과 신규 로직이 공존하며 진행되는 점진적인 리팩토링
- 로또 요구사항을 파악한다.
- 요구사항에 대한 구현을 완료한 후 자신의 github 아이디에 해당하는 브랜치에 Pull Request(이하 PR)를 통해 코드 리뷰 요청을 한다.
- 코드 리뷰 피드백에 대한 개선 작업을 하고 다시 PUSH한다.
- 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다.
- 사용자가 입력한 값에 따라 사칙연산을 수행할 수 있는 계산기를 구현한다.
- 덧셈
- 뺄셈
- 곱셈
- 나눗셈
- 입력 문자열의 숫자와 사칙 연산 사이에는 반드시 빈 공백 문자열이 있다고 가정한다.
- 나눗셈의 경우 결과 값을 정수로 떨어지는 값으로 한정한다.
- 사칙연산의 계산 우선순위가 아닌 입력 값에 따라 계산 순서가 결정된다.
- 입력값이 null 이거나 빈 공백 문자일 경우 IllegalArgumentException throw
- 사칙연산 기호가 아닌 경우 IllegalArgumentException throw
- Sign 클래스 생성 후 검증
- indent depth는 최대 1단계까지
- 메소드 크기가 최대 10라인 이하(한가지 일만 하도록 한다.)
- else 를 사용하지 않는다.
- Stack -> Queue 변경
- while -> for 변경
- Sign Enum 구현
- 연산작업에 대한 위치 고민
- Sign Enum 에게 위임
- Main 클래스 생성
- 멤버 변수로 정의하면 객체는 상태를 갖게 됨, 멤버변수 선언 지양
- Calculator 내부 메서드 divide 의 이름 고민
- 멤버변수가 아닌 매개 변수로 넘기면서 자연스러운 표현 고민
- Calculator 클래스 전체 구조 수정
- 사용자 입력 기능 추가
- Sign의 validate 방식 변경
- Sign의 of()와 calculate() 테스트 분리
- Sign 구조 개선
- 로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다.
- 로또 한 장의 가격은 1000원이다.
- 금액을 입력받아 로또를 구매한다.
- 로또 번호는 1부터 45까지이며, 로또 한 세트의 번호는 중복되지 않는다.
- 지난 주 당첨 번호를 입력받아 당첨 통계
- 6개로 이루어진 로또 set를 로또 갯수만큼 생성한다.
- 로또 1개를 생성한다.
- Colletions.sort() 메소드로 정렬
- 당첨 통계
- 지난 당첨 로또 생성
- 당첨 로또 중 3, 5, 6개 일치 시 당첨으로 간주
- 등수별 당첨 갯수 반환
- 총 수익률
- Lotto 순위 enum 추가
- 몇 개일 때 당첨인지
- 당첨금은 얼마인지
- LottosResult 가 관리하는 것
- 전체 수익률
- 등수당 당첨 갯수
- Lotto 순위 enum 추가
- 모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. (UI 로직 제외)
- UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다.
- indent depth는 1까지 허용
- 함수(메소드) 길이가 15라인을 넘어가지 않도록 구현한다.
- else 예약어를 사용하지 않는다.
- LottoGenerator 테스트를 위한 동작 분리
- Lotto 내 변수의 재사용성 고민
- 외부에서 주입받은 변수 외 멤버변수 삭제
- Lotto의 생성자 2개 중 테스트를 위한 생성자를 없애기
- 생성자 방식 변경
- Lotto의 멤버변수 ranking의 위치 고민
- 삭제
- Lotto의 멤버변수 matchingCount를 쓰지 않기
- 삭제, 메서드 이용하여 return
- Stream의 generate와 limit 활용
- 수익률 계산 역할의 위치 고민
- Map.of() 활용
- Ranking 내 Map 삭제
- increaseMatchingCount() 구조 변경
- LottoGenerator 의 lottos() 구조 변경
- Stream 표현식을 가독성있게 변경
- 로또 2등 당첨을 구현한다.
- 당첨 확인을 위해 보너스 번호를 별도로 입력받는다.
- 2등 당첨은 5개 번호 일치 + 보너스 번호 일치이다.
- 당첨 통계에 2등을 추가한다.
- java enum을 적용한다.
- 일급 콜렉션을 사용한다.
- 2등을 찾는 로직 개선
- 사용자는 수동으로 구매할 로또 수를 입력한다.
- 사용자는 수동으로 구매할 번호 6개를 구매할 수량만큼 입력할 수 있다.
- 사용자가 입력한 갯수 외 나머지는 자동으로 생성한다.
- LottoNo를 이용해서 로또 각 번호의 유효성을 검사한다.
- Lotto의 각 번호
- WinningLotto의 보너스 번호
- 사용자가 잘못된 값을 입력했을 때 java exception으로 예외 처리를 한다.
- java8에 추가된 Optional 을 적용해 NullPointerException이 발생하지 않도록 한다.
- 파라미터의 의미를 명시적으로 드러내주기 위해 변수로 추출
- 클래스명이나 변수명에 줄임말을 쓰지 않고, 컬렉션은 복수로 표현
- number -> new LottoNo(number) 에서 생성자 레퍼런스 활용
- Lotto ranking 메서드 내 당첨 로또와 비교하는 부분에서 WinningLotto에게 contains를 직접 질의하기