해당 객체가 가지고 있는 역할이 굉장히 많은 것 같아요 🤔
적절한 책임을 나누어 객체를 분리해보면 좋겠습니다!
로또 번호가 42까지 밖에 안보이네요 @_@
또한 값의 범위가 커질수록 하드코딩 하는 것이 힘들어질 수 있기 때문에 범위를 통해 번호를 생성해보면 좋을 것 같아요!
InputView의 경우 LottoApp에서 사용하고 ResultView의 경우 도메인 내부에 존재하도록 구현해주셨네요!
도메인 내부에 View의 로직이 존재한다면 어떠한 문제가 있을지 고민해보아요
String 타입으로 로또의 번호라는 사실을 검증할 수 있을까요?
규칙 3: 모든 원시값과 문자열을 포장한다.을 통해 값들을 포장하여 해당 문제를 해결해 볼 수 있을 것 같습니다 :)
이전에 멘토님께서 위와 같은 피드백을 주셨다.
피드백을 바탕으로 새롭게 코드를 구현해 보았다.
먼저 클래스를 좀 더 세분화 해 보았다.
이전에는 LottoMachine에서 모든 기능을 구현하였다면
이번에는 Lotto, LottoMachine, Caluculator, LastWinningLottoNumberChecker 등을 구현하였다.
Lotto
-로또를 발행
Calculator
- 발행된 로또와, 이전 당첨번호와 비교하는 로직
LastWinningLottoNumberChecker
- 이전 당첨번호를 사용자가 잘 입력했는지 확인하는 부분
LottoMachine
- 전반적인 기능을 실행하는 부분이다.
package step2.domain;
import java.util.ArrayList;
import java.util.Collections;
public class Lotto {
static final int MIN_OF_LOTTO_NUMBER = 1;
static final int MAX_OF_LOTTO_NUMBER = 45;
static final int NUM_OF_LOTTO_NUMBER = 6;
static ArrayList<Integer> lottoNumberList = new ArrayList<>();
public Lotto() {
makeLottoNumberList();
}
public ArrayList<Integer> issueLotto() {
ArrayList<Integer> lotto = new ArrayList<>();
Collections.shuffle(lottoNumberList);
for (int i = 0; i < NUM_OF_LOTTO_NUMBER; i++) {
lotto.add(lottoNumberList.get(i));
}
printIssuedLottoNumber(lotto);
return lotto;
}
private void printIssuedLottoNumber(ArrayList lotto) {
System.out.println(lotto);
}
public ArrayList<Integer> makeLottoNumberList() {
for (int i = MIN_OF_LOTTO_NUMBER; i < MAX_OF_LOTTO_NUMBER; i++) {
lottoNumberList.add(i);
}
return lottoNumberList;
}
}
package step2.domain;
import step2.util.LastWinningLottoNumberChecker;
import java.util.ArrayList;
public class LottoMachine {
static int numOfLotto;
static String lastWinningLottoNum;
static LastWinningLottoNumberChecker lastWinningLottoNumberChecker;
static Lotto lotto = new Lotto();
static ArrayList<Integer> lastWinningLottoNumberArray;
static ArrayList<ArrayList> issuedLottolist = new ArrayList<>();
public LottoMachine(int numOfLotto, String lastWinningLottoNum) {
this.numOfLotto = numOfLotto;
this.lastWinningLottoNum = lastWinningLottoNum;
}
public ArrayList<ArrayList> run() {
getLottoList();
lastWinningLottoNumberChecker = new LastWinningLottoNumberChecker(lastWinningLottoNum);
lastWinningLottoNumberArray = lastWinningLottoNumberChecker.getLottoWinningNumberArray();
return issuedLottolist;
}
public ArrayList<ArrayList> getLottoList() {
for (int i = 0; i < numOfLotto; i++) {
issuedLottolist.add(lotto.issueLotto());
}
return issuedLottolist;
}
public ArrayList<Integer> getLastWinningLottoNumberArray() {
return lastWinningLottoNumberArray;
}
}
package step2.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Calculator {
static ArrayList<ArrayList> issuedLottolist;
static final int NUM_OF_LOTTO_NUMBERS = 6;
static int[] lottoResultArray;
static ArrayList<Integer> lastWinningLottoNumberArray;
public Calculator(ArrayList<ArrayList> issuedLottolist, ArrayList<Integer> lastWinningLottoNumberArray) {
this.issuedLottolist = issuedLottolist;
this.lastWinningLottoNumberArray = lastWinningLottoNumberArray;
}
public void run() {
lottoResultArray = new int[NUM_OF_LOTTO_NUMBERS+1];
for (ArrayList<Integer> issuedLotto : issuedLottolist) {
calcMatchedLottoNum(issuedLotto);
}
}
public void calcMatchedLottoNum(ArrayList<Integer> issuedLotto) {
List<Integer> matchedLottoList = issuedLotto.stream()
.filter(num -> lastWinningLottoNumberArray.contains(num))
.collect(Collectors.toList());
lottoResultArray[matchedLottoList.size()]++;
}
public int[] getLottoResultArray() {
return lottoResultArray;
}
}
package step2.util;
import java.util.ArrayList;
public class LastWinningLottoNumberChecker {
private static final String LOTTO_COUNT_ERROR_MESSAGE = "로또 당첨번호는 6개를 입력하세요. 당첨번호는 ', '로 구분을 하고 있습니다.";
private static final String LOTTO_NUMBER_RANGE_ERROR_MESSAGE = "로또 당첨번호는 1과 45 사이의 정수이어야 합니다.";
private static final String LOTTO_DELIMITER = ", ";
private static final int MIN_OF_LOTTO_NUMBER = 1;
private static final int MAX_OF_LOTTO_NUMBER = 45;
private static final int COUNT_OF_LOTTO_WINNING_NUMBER = 6;
private final ArrayList<Integer> lastWinningLottoNumberArray;
public LastWinningLottoNumberChecker(String lastWinningLottoNum) {
ArrayList<Integer> lottoNumberIntegerArray = makeIntegerArray(validateCountOfLotto(lastWinningLottoNum));
lottoLoop(lottoNumberIntegerArray);
this.lastWinningLottoNumberArray = lottoNumberIntegerArray;
}
private ArrayList<Integer> makeIntegerArray(String[] lottoNumberStringArray) {
ArrayList<Integer> lottoNumberIntegerArray = new ArrayList<>();
for (int i = 0; i < lottoNumberStringArray.length; i++) {
lottoNumberIntegerArray.add(Integer.parseInt(lottoNumberStringArray[i]));
}
return lottoNumberIntegerArray;
}
public void lottoLoop(ArrayList<Integer> lottoNumberIntegerArray) {
for (int lottoNumber : lottoNumberIntegerArray) {
validatePositiveLottoNum(lottoNumber);
}
}
private void validatePositiveLottoNum(int lottoNumber) {
if (lottoNumber < MIN_OF_LOTTO_NUMBER || lottoNumber > MAX_OF_LOTTO_NUMBER) {
throw new IllegalArgumentException(LOTTO_NUMBER_RANGE_ERROR_MESSAGE);
}
}
public String[] validateCountOfLotto(String lastWinningLottoNum) {
String[] lottoNumberStringArray = lastWinningLottoNum.split(LOTTO_DELIMITER);
int numOfLotto = lottoNumberStringArray.length;
if (numOfLotto != COUNT_OF_LOTTO_WINNING_NUMBER) {
throw new IllegalArgumentException(LOTTO_COUNT_ERROR_MESSAGE);
}
return lottoNumberStringArray;
}
public ArrayList<Integer> getLottoWinningNumberArray() {
return lastWinningLottoNumberArray;
}
}
package step2;
import step2.domain.LottoMachine;
import step2.util.Calculator;
import step2.view.InputView;
import step2.view.ResultView;
import java.util.ArrayList;
public class LottoApp {
public static void main(String[] args) {
InputView inputView = new InputView();
ResultView resultView = new ResultView();
int numOfLotto = inputView.requestInput();
String lastWinningLottoNum = inputView.requestWinningLottoNumber();
LottoMachine lottoMachine = new LottoMachine(numOfLotto, lastWinningLottoNum);
ArrayList<ArrayList> issuedLottolist = lottoMachine.run();
ArrayList<Integer> lastWinningLottoNumberArray = lottoMachine.getLastWinningLottoNumberArray();
Calculator calculator = new Calculator(issuedLottolist, lastWinningLottoNumberArray);
calculator.run();
int[] lottoResultArray = calculator.getLottoResultArray();
resultView.printMatchedLottoRecord(lottoResultArray, numOfLotto);
}
}
package step2.view;
import java.util.Scanner;
public class InputView {
static final String INPUT_MESSAGE = "구입 금액을 입력해주세요.";
static final String INPUT_INFO_MESSAGE = "개를 구매했습니다.";
static final String INPUT_LAST_LOTTO_NUMBER = "지난 주 당첨 번호를 입력해 주세요.";
private static final int chargeOfLotto = 1000;
static Scanner sc = new Scanner(System.in);
public int requestInput() {
System.out.println(INPUT_MESSAGE);
int charge = sc.nextInt();
sc.nextLine();
int numOfLotto = charge/chargeOfLotto;
System.out.println(numOfLotto+INPUT_INFO_MESSAGE);
return numOfLotto;
}
public String requestWinningLottoNumber() {
System.out.println(INPUT_LAST_LOTTO_NUMBER);
String lastWinningLottoNum = sc.nextLine();
return lastWinningLottoNum;
}
}
package step2.view;
import java.util.ArrayList;
import java.util.Arrays;
public class ResultView {
static int[] charge = {0,0,0,5000,50000,1500000,2000000000};
public void printIssuedLottoNumber(String[] lotto) {
System.out.println(Arrays.toString(lotto));
}
public void printMatchedLottoRecord(int[] matchedLottoRecordArray, int numOfLotto) {
int totalRevenue = 0;
System.out.println("당첨 통계");
System.out.println("-------");
for (int i = 1; i <= 6; i++) {
System.out.printf("%s 개 일치 (%s) %s개\n",i,charge[i],matchedLottoRecordArray[i]);
totalRevenue += charge[i] * matchedLottoRecordArray[i];
}
double yield = totalRevenue / (double)(numOfLotto * 1000);
printResultMessage(yield);
}
private void printResultMessage(double yield) {
if (yield < 1) {
System.out.printf("총 수익률은 %s입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임)",yield);
return;
}
if (yield >= 1) {
System.out.printf("총 수익률은 %s입니다.(기준이 1이기 때문에 결과적으로 이익이라는 의미임)",yield);
return;
}
}
}
'강의 > TDD, Clean Code with Java 12기' 카테고리의 다른 글
[로또] step2 - 로또(자동) - 최종 피드백 (22일차) (0) | 2021.08.10 |
---|---|
[로또] step2 - 로또(자동) - 피드백 및 피드백 반영(21일차) (0) | 2021.08.09 |
[로또] step2 - 로또(자동) - 피드백 (20일차) (0) | 2021.08.08 |
[로또] step1 - 문자열 덧셈 계산기 - 피드백(20일 차) (0) | 2021.08.08 |
[로또] step2 - 로또(자동) (18일차) (0) | 2021.08.06 |