Search
Duplicate

2. [클린 코드 with Java] 2단계 - 로또(자동)

링크
점수
⭐️⭐️⭐️⭐️
완료일
2023/04/29
상태
완료
유형
인강

2단계 - 로또(자동)

기능 요구사항

로또 구입 금액을 입력하면 구입 금액에 해당하는 로또를 발급해야 한다.
로또 1장의 가격은 1000원이다.
구입금액을 입력해 주세요. 14000 14개를 구매했습니다. [8, 21, 23, 41, 42, 43] [3, 5, 11, 16, 32, 38] [7, 11, 16, 35, 36, 44] [1, 8, 11, 31, 41, 42] [13, 14, 16, 38, 42, 45] [7, 11, 30, 40, 42, 43] [2, 13, 22, 32, 38, 45] [23, 25, 33, 36, 39, 41] [1, 3, 5, 14, 22, 45] [5, 9, 38, 41, 43, 44] [2, 8, 9, 18, 19, 21] [13, 14, 18, 21, 23, 35] [17, 21, 29, 37, 42, 45] [3, 8, 27, 30, 35, 44] 지난 주 당첨 번호를 입력해 주세요. 1, 2, 3, 4, 5, 6 당첨 통계 --------- 3개 일치 (5000)- 14개 일치 (50000)- 05개 일치 (1500000)- 06개 일치 (2000000000)- 0개 총 수익률은 0.35입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임)
Java
복사

힌트

로또 자동 생성은 Collections.shuffle() 메소드 활용한다.
Collections.sort() 메소드를 활용해 정렬 가능하다.
ArrayList의 contains() 메소드를 활용하면 어떤 값이 존재하는지 유무를 판단할 수 있다.

프로그래밍 요구사항

모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. 단, UI(System.out, System.in) 로직은 제외
핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다.
UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다.
indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다.
예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다.
함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.
함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.
모든 로직에 단위 테스트를 구현한다. 단, UI(System.out, System.in) 로직은 제외
핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다.
UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다.
자바 코드 컨벤션을 지키면서 프로그래밍한다.
else 예약어를 쓰지 않는다.
힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.

기능 목록 및 commit 로그 요구사항

기능을 구현하기 전에 README.md 파일에 구현할 기능 목록을 정리해 추가한다.
git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가한다.

피드백

리뷰어 : 당첨에 대한 정보를 여기서 책임 갖고 관리한다는 측면에서는, FIRST_PLACE... 와 같은 스태틱 변수들을 다른 곳에 두기보단 여기에 두고 계속 사용하는 것이 좋을 것 같습니다.
생각정리 : 맨 처음에는 서브스 레이어에서 enum까지 구현하려고 했는데, 옮기지 못하였다. 좀 더 디테일에 신경쓰자!
public class ProfitCalculatorService { public static final int FIRST_PLACE = 6; public static final int SECOND_PLACE = 5; public static final int THIRD_PLACE = 4; public static final int FOURTH_PLACE = 3; public static final int EMPTY_PLACE = 0; private Lottos lottos; private int purchaseAmount; private Map<String, Integer> winningCount = new HashMap<>(); public ProfitCalculatorService(Lottos lottos, int purchaseAmount) { this.lottos = lottos; this.purchaseAmount = purchaseAmount; }
Java
복사
사용하는 클래스
package step2.domain.model; import java.util.Arrays; import static step2.domain.ProfitCalculatorService.*; public enum WinningAmountByRank { FIRST(FIRST_PLACE, 2000000000, "FIRST_PLACE"), SECOND(SECOND_PLACE, 1500000, "SECOND_PLACE"), THIRD(THIRD_PLACE, 50000, "THIRD_PLACE"), FOURTH(FOURTH_PLACE, 5000, "FOURTH_PLACE"), EMPTY(EMPTY_PLACE, 0, "EMPTY_PLACE"); private final int rank; private final int amount; private final String key; WinningAmountByRank(int rank, int amount, String key) { this.rank = rank; this.amount = amount; this.key = key; } public static WinningAmountByRank from(int rank) { return Arrays.stream(values()) .filter(value -> rank == value.rank) .findFirst() .orElse(WinningAmountByRank.EMPTY); } public int getAmount() { return amount; } public int getRank() { return rank; } public String getKey() { return key; } }
Java
복사
다음과 같이 변경
package step2.domain.model; import java.util.Arrays; public enum WinningAmountByRank { FIRST(WinningAmountByRank.FIRST_PLACE, 2000000000, "FIRST_PLACE"), SECOND(WinningAmountByRank.SECOND_PLACE, 1500000, "SECOND_PLACE"), THIRD(WinningAmountByRank.THIRD_PLACE, 50000, "THIRD_PLACE"), FOURTH(WinningAmountByRank.FOURTH_PLACE, 5000, "FOURTH_PLACE"), EMPTY(WinningAmountByRank.EMPTY_PLACE, 0, "EMPTY_PLACE"); public static final int FIRST_PLACE = 6; public static final int SECOND_PLACE = 5; public static final int THIRD_PLACE = 4; public static final int FOURTH_PLACE = 3; public static final int EMPTY_PLACE = 0; private final int rank; private final int amount; private final String key; WinningAmountByRank(int rank, int amount, String key) { this.rank = rank; this.amount = amount; this.key = key; } public static WinningAmountByRank from(int rank) { return Arrays.stream(values()) .filter(value -> rank == value.rank) .findFirst() .orElse(WinningAmountByRank.EMPTY); } public int getAmount() { return amount; } public int getRank() { return rank; } public String getKey() { return key; } }
Java
복사
리뷰어 : 무엇에 대한 전략인지 네이밍이 더 구체적이었으면 합니다.
생각정리 : 어떤 전략적 패턴인지 좀 더 명확하게 작성.
package step2.domain.strategy.price; public interface Strategy {
Java
복사
다음과 같이 변경
package step2.domain.strategy.price; public interface PriceStrategy { int buyLotto(int purchaseAmount); }
Java
복사
깃허브링크 :
2999
pull

후기

오늘은 로또(자동)을 구현하였다. 점점 더 발전하는 것인가? 오늘은 리뷰가 이전보다는 많이 줄어든 느낌이 든다. 신경 쓰고, 리뷰해 주는 것을 적용하도록 노력하자! 의식적인 변화!!
출처