-
Notifications
You must be signed in to change notification settings - Fork 330
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1단계 - 로또 구현] 검프(김태정) 미션 제출합니다. (#269)
* refactor: remove spark library, html * docs: 기능 요구사항 정리 구현할 기능을 README로 정리하였음 * docs: 객체 메세지 정의 협력에 필요한 메세지를 먼저 정의 하였음. * docs: 객체 협력 정리 이미지를 통해 객체 협력을 정리하였다 * feat: 보장된 로또 번호로 한 로또를 생성한다 중복 검사, 번호 검사, 갯수 검사 완료 * feat: 보장된 구입금액을 입력 받는다. 음수, 실수가 들어모면 에러가 발생한다. * feat: 구입금액 따른 로또의 갯수를 구한다. * feat: 보장된 당첨 번호를 입력한다. 보장된 당첨 번호(중복되지 않은 1~45의 숫자, 6개의 숫자) 보장되지 않은 당첨번호 에러가 발생한다. * feat: LottoNumber 객체 생성 로또 번호를 가질 LottoNumber 객체 생성 및 검증 완료 * feat: LottoNumbers 객체 생성 LottoNumber을 관리할 LottoNumbers 객체를 생성 및 검증하였음 * refactor: Lotto 및 WinningLotto의 인스턴스 변수 변경 private final List<Integer> lottoNumbers; -> private final LottoNumbers lottoNumbers; * feat: 보장된 보너스 볼을 입력 받는다 BonusNumber 객체 생성 및 검증 완료 * refactor: BonusNumber 정적 팩토리 메서드 생성 생성자를 private으로 감추고, 정적 팩토리 메서드를 생성하였음 * feat: 구현 부분 구입금액 입력 확인 구현 부분에서 구입금액을 입력 후 저장하였음 * feat: 랜덤 로또 번호 생성 RandomLottoUtil 객체 생성 * feat: 구입금액 입력 화면 출력 로직 생성 * refactor: Budget 메소드 추가 int value를 반환하는 Budget메소드를 추가하였음. * feat: 구매 갯수 출력 로직 작성 * feat: 로또 갯수만큼 보장된 로또번호를 출력한다. dto를 통해 로또 번호 출력 * refactor: LottoGameMachine::gameStart() 내부 구현 변경 LottoGameMachine의 책임을 Screen에 옮김 * feat: 임시 저장 * feat: 콘솔 창에 당첨번호를 입력한다. * feat: 로또 당첨 확인 로직 구현 * feat: 보너스 볼 포함 당첨 현황을 구한다 * feat: 당첨 통계 출력 * feat: 수익률 계산 로직 * refactor: naming 변경 Number -> ball 로 변경하였음 * refactor: dto naming 변경 dto의 이름을 변경하였음 * refactor: BonusBall 객체 제거 분리될 만큼의 책임을 가지지 않기 때문에 제거함. * refactor: WinningLotto, LottoBalls 책임 변경 - [x] LottoBalls 생성자 책임 정의 - > LottoBalls 생성자 제거 - [x] 입력 파싱 책임 제거 - [x] gnerate 제거 - [x] of 제거 - [x] winngLotto 생성 로직 변경 * refactor: 클래스 네이밍 변경 Lotto -> LottoTicket Lottos -> LottoTickets LottoCount -> TicketCount * refactor: Budget 클래스 BettingMoney로 변경 Budget의 책임이 모호하여 BettingMoney로 변경함. * refactor: DTO 제거 및 책임 분리 LottoService를 추가하여 LottoGameMachine의 책임을 이동하였고, DTO를 제거하면서 필요한 로직을 수정함. result 클래스 변경 및 테스트를 추가하였음 * refactor: LottoRank 클래스 수정 - [x] 사용되지 않는 값 제거 - [x] 메서드 네이밍 변경 * refactor: 에러 출력메세지 상수 활용 * refactor: LottoGameScreen 변경 출력 로직 변경 및 변경으로 인한 LottoRank 변경 * refactor: test 한글 네이밍 영어로 변경 모든 테스트의 네이밍을 변경하였음 * refactor: code convention 의미없는 띄어쓰기 삭제 맟, 메소드 선언 순서 변경 * docs: 리팩토링 목록 정리 리팩토링한 목록을 정리하였음 Co-authored-by: 포비 <pobi@woowahan.com>
- Loading branch information
Showing
32 changed files
with
1,119 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
# java-lotto | ||
# java-lottoTicket | ||
로또 미션 진행을 위한 저장소 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
## 객체 협력 정리 | ||
 | ||
|
||
|
||
## 매세지 정의 | ||
- 로또를 구매하라 | ||
- 로또를 생성하라 | ||
- 로또 갯수만큼 로또 번호를 생성하라 | ||
- 로또 번호를 생성하라 | ||
- 한 게임을 생성하라 | ||
- 구입금액을 입력하라 | ||
- 당첨 번호를 입력하라 | ||
- 보너스 볼을 입력하라 | ||
- 로또 갯수를 구하라 | ||
- 생성된 로또번호를 출력하라 | ||
- 당첨 갯수를 구하라 | ||
- 수익률을 계산하라 | ||
|
||
## 기능 요구사항 정리 | ||
- [x] 구현 부분 구입금액 입력 확인 | ||
- [x] 보장된 구입금액을 입력 받는다. | ||
- 보장된 구입금액(로또 티켓 구입 금액보다 큰 양수의 숫자) | ||
- [x] 보장된 구입금액이 아니면 에러가 발생한다. | ||
- `IllegalArgumentException` | ||
- [x] 구입금액 따른 로또의 갯수를 구한다. | ||
- [x] 보장된 로또 번호로 한 로또를 생성한다. | ||
- 보장된 로또 번호(중복되지 않은 1~45의 숫자이며, 6개의 숫자) | ||
- [x] 로또 갯수만큼 보장된 로또번호를 출력한다. | ||
- 보장된 로또번호(중복되지 않은 1~45의 숫자이며, 6개의 숫자) | ||
- [x] 콘솔 창에 당첨번호를 입력한다. | ||
- [x] 보장된 당첨 번호를 입력한다. | ||
- 보장된 당첨 번호(중복되지 않은 1~45의 숫자, 6개의 숫자) | ||
- [x] 보장된 당첨 번호가 아니면 에러가 발생한다. | ||
- `IllegalArgumentException` | ||
- [x] 보장된 보너스 볼을 입력 받는다. | ||
- 보장된 보너스 볼(보장된 당첨 번호와 중복되지 않는 1~45의 숫자) | ||
- [x] 보장된 보너스 볼이 아니면 에러가 발생한다. | ||
- `IllegalArgumentException` | ||
- [x] 보너스 볼 포함 당첨 현황을 구한다. | ||
- [x] 당첨 통계를 출력한다. | ||
- [x] 수익률을 출력한다. | ||
|
||
## 리펙토링 목록 정리 | ||
- [x] DTO 제거기(DTO 없이 view에 값을 전달 할 수 있다.) | ||
- [x] 책임에 대해 한번더 생각하기 | ||
- [x] BonusBall 제거 | ||
- [x] LottoGameMachine 책임 분리하기 | ||
- [x] 입력 파싱 책임 제거 | ||
- [x] gnerate 제거 | ||
- [x] of 제거 | ||
- [x] 테스트메서드 한글 이름 영어로 변경 (의도를 더 드러내자) | ||
- [x] 사용되지 않는 값 제거 | ||
- [x] 사용되지 않은 메서드 제거 | ||
- [x] 제네릭 빠진 것 확인 | ||
- [x] DisplayName 의도를 더 정확히 드러내 | ||
|
||
|
||
## 프로그래밍 요구사항 | ||
- indent(인덴트, 들여쓰기) depth를 2단계에서 1단계로 줄여라. | ||
- depth의 경우 if문을 사용하는 경우 1단계의 depth가 증가한다. if문 안에 while문을 사용한다면 depth가 2단계가 된다. | ||
- else를 사용하지 마라. | ||
- 메소드의 크기가 최대 10라인을 넘지 않도록 구현한다. | ||
- method가 한 가지 일만 하도록 최대한 작게 만들어라. | ||
- 배열 대신 ArrayList를 사용한다. | ||
- java enum을 적용해 프로그래밍을 구현한다. | ||
- 규칙 3: 모든 원시값과 문자열을 포장한다. | ||
- 규칙 5: 줄여쓰지 않는다(축약 금지). | ||
- 규칙 8: 일급 콜렉션을 쓴다. | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import domain.LottoGameMachine; | ||
import service.LottoService; | ||
import view.LottoGameScreen; | ||
import view.MainScreen; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
LottoGameMachine lottoGameMachine = new LottoGameMachine(); | ||
LottoService lottoService = new LottoService(lottoGameMachine); | ||
GameManageApplication gameManageApplication = new GameManageApplication(new MainScreen(), new LottoGameScreen(), lottoService); | ||
gameManageApplication.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import domain.bettingMoney.BettingMoney; | ||
import domain.lotto.LottoTickets; | ||
import domain.lotto.TicketCount; | ||
import domain.lotto.WinningLotto; | ||
import domain.result.Result; | ||
import service.LottoService; | ||
import util.InputUtil; | ||
import view.LottoGameScreen; | ||
import view.MainScreen; | ||
import view.dto.LottoGameResultDto; | ||
|
||
import java.util.Set; | ||
|
||
public class GameManageApplication { | ||
private final MainScreen mainScreen; | ||
private final LottoGameScreen lottoGameScreen; | ||
private final LottoService lottoService; | ||
|
||
public GameManageApplication(final MainScreen mainScreen, final LottoGameScreen lottoGameScreen, LottoService lottoService) { | ||
this.mainScreen = mainScreen; | ||
this.lottoGameScreen = lottoGameScreen; | ||
this.lottoService = lottoService; | ||
} | ||
|
||
public void run() { | ||
BettingMoney bettingMoney = getBettingMoney(); | ||
TicketCount ticketCount = getTicketCount(bettingMoney); | ||
mainScreen.showTicketCount(ticketCount); | ||
LottoTickets lottoTickets = lottoService.getLottoTickets(bettingMoney); | ||
lottoGameScreen.showAllLottoStatus(lottoTickets.getLottoTickets()); | ||
WinningLotto winningLotto = getWinningLotto(); | ||
|
||
Result result = new Result(lottoTickets, winningLotto); | ||
lottoGameScreen.showGameResult(new LottoGameResultDto(result.getResults())); | ||
lottoGameScreen.showRevenueResult(result.findEarningsRate(bettingMoney)); | ||
} | ||
|
||
private WinningLotto getWinningLotto() { | ||
lottoGameScreen.confirmWinningLotto(); | ||
Set<Integer> winningNumbers = InputUtil.inputWinningNumbers(); | ||
lottoGameScreen.confirmBonusLotto(); | ||
int bonusNumber = InputUtil.inputBonusNumber(); | ||
return new WinningLotto(winningNumbers, bonusNumber); | ||
} | ||
|
||
private TicketCount getTicketCount(final BettingMoney bettingMoney) { | ||
int ticketCount = bettingMoney.getTicketCount(); | ||
return TicketCount.of(ticketCount); | ||
} | ||
|
||
private BettingMoney getBettingMoney() { | ||
mainScreen.showInputMoney(); | ||
int input = InputUtil.nextInt(); | ||
return BettingMoney.of(input); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package domain; | ||
|
||
import domain.ball.LottoBall; | ||
import domain.ball.LottoBalls; | ||
import domain.bettingMoney.BettingMoney; | ||
import domain.lotto.LottoTicket; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class LottoGameMachine { | ||
public List<LottoTicket> buyTickets(BettingMoney bettingMoney) { | ||
int ticketCount = bettingMoney.getTicketCount(); | ||
return IntStream.range(0, ticketCount) | ||
.mapToObj(count -> makeTicket()) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private LottoTicket makeTicket() { | ||
List<LottoBall> lottoBalls = LottoBalls.getRandomLottoBalls(); | ||
return new LottoTicket(new LottoBalls(lottoBalls)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package domain.ball; | ||
|
||
import java.util.Objects; | ||
|
||
public class LottoBall implements Comparable<LottoBall> { | ||
public static final int MIN_LOTTO_VALUE = 1; | ||
public static final int MAX_LOTTO_VALUE = 45; | ||
public static final String PERMIT_LOTTO_NUMBER_EXCEPTION_MESSAGE = "%d~%d 사이의 번호만 허용합니다."; | ||
|
||
private final int value; | ||
|
||
public LottoBall(final int value) { | ||
validateNumber(value); | ||
this.value = value; | ||
} | ||
|
||
private void validateNumber(final int value) { | ||
if (!isBetweenNumber(value)) { | ||
throw new IllegalArgumentException(String.format(PERMIT_LOTTO_NUMBER_EXCEPTION_MESSAGE, MIN_LOTTO_VALUE, MAX_LOTTO_VALUE)); | ||
} | ||
} | ||
|
||
private boolean isBetweenNumber(final int number) { | ||
return number >= MIN_LOTTO_VALUE && number <= MAX_LOTTO_VALUE; | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
LottoBall that = (LottoBall) o; | ||
return value == that.value; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(value); | ||
} | ||
|
||
@Override | ||
public int compareTo(LottoBall o) { | ||
if (this.value > o.value) { | ||
return 1; | ||
} | ||
return -1; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return value + " "; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package domain.ball; | ||
|
||
import domain.result.LottoRank; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
import static domain.ball.LottoBall.MAX_LOTTO_VALUE; | ||
import static domain.ball.LottoBall.MIN_LOTTO_VALUE; | ||
|
||
public class LottoBalls { | ||
private static final int LOTTO_BALL_SIZE = 6; | ||
|
||
private final List<LottoBall> lottoBalls; | ||
|
||
public LottoBalls(final List<LottoBall> lottoBalls) { | ||
List<LottoBall> copy = new ArrayList<>(lottoBalls); | ||
validateLottoNumbers(copy); | ||
this.lottoBalls = copy; | ||
} | ||
|
||
public static List<LottoBall> getRandomLottoBalls() { | ||
List<LottoBall> lottoBalls = IntStream.rangeClosed(MIN_LOTTO_VALUE, MAX_LOTTO_VALUE) | ||
.mapToObj(LottoBall::new) | ||
.collect(Collectors.toList()); | ||
Collections.shuffle(lottoBalls); | ||
return lottoBalls.stream() | ||
.limit(LOTTO_BALL_SIZE) | ||
.sorted() | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public List<LottoBall> getLottoBalls() { | ||
List<LottoBall> copy = new ArrayList<>(this.lottoBalls); | ||
return Collections.unmodifiableList(copy); | ||
} | ||
|
||
public LottoRank matchCount(LottoBalls lottoBalls, LottoBall bonusBall) { | ||
int count = (int) this.lottoBalls.stream() | ||
.filter(lottoBalls::contains) | ||
.count(); | ||
|
||
boolean containBonus = this.lottoBalls.stream() | ||
.anyMatch(bonusBall::equals); | ||
|
||
return LottoRank.findRankByBonusAndMatches(containBonus, count); | ||
} | ||
|
||
private void validateLottoNumbers(final List<LottoBall> lottoBalls) { | ||
validateDuplicate(lottoBalls); | ||
validateSize(lottoBalls); | ||
} | ||
|
||
private void validateDuplicate(final List<LottoBall> lottoBalls) { | ||
boolean isUnique = lottoBalls.stream() | ||
.allMatch(new HashSet<>()::add); | ||
if (!isUnique) { | ||
throw new IllegalArgumentException(String.format("로또 번호에 중복된 값이 있습니다. 다시 입력해주세요. 입력값 %s", lottoBalls.toString())); | ||
} | ||
} | ||
|
||
private void validateSize(final List<LottoBall> lottoNumbers) { | ||
if (lottoNumbers.size() != LOTTO_BALL_SIZE) { | ||
throw new IllegalArgumentException(String.format("%d개의 로또 번호가 필요합니다.", LOTTO_BALL_SIZE)); | ||
} | ||
} | ||
|
||
private boolean contains(LottoBall lottoBall) { | ||
return this.lottoBalls.contains(lottoBall); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package domain.bettingMoney; | ||
|
||
import java.math.BigDecimal; | ||
|
||
import static domain.lotto.LottoTicket.TICKET_PRICE; | ||
|
||
public class BettingMoney { | ||
private static final String NOT_ENOUGH_MONEY_EXCEPTION_MESSAGE = "%d 이상의 금액만 가능합니다. 현재 입력 금액: %d"; | ||
|
||
private final int bettingMoney; | ||
|
||
private BettingMoney(final int bettingMoney) { | ||
validateMoney(bettingMoney); | ||
this.bettingMoney = bettingMoney; | ||
} | ||
|
||
public static BettingMoney of(final int bettingMoney) { | ||
return new BettingMoney(bettingMoney); | ||
} | ||
|
||
public int getTicketCount() { | ||
return this.bettingMoney / TICKET_PRICE; | ||
} | ||
|
||
public BigDecimal getEarningRate(final int prizeMoney) { | ||
BigDecimal bettingMoney = BigDecimal.valueOf(this.bettingMoney); | ||
BigDecimal prize = BigDecimal.valueOf(prizeMoney); | ||
return prize.divide(bettingMoney); | ||
} | ||
|
||
private void validateMoney(final int bettingMoney) { | ||
if (bettingMoney < TICKET_PRICE) { | ||
throw new IllegalArgumentException(String.format(NOT_ENOUGH_MONEY_EXCEPTION_MESSAGE, TICKET_PRICE, bettingMoney)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package domain.lotto; | ||
|
||
import domain.ball.LottoBall; | ||
import domain.ball.LottoBalls; | ||
import domain.result.LottoRank; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class LottoTicket { | ||
public static final int TICKET_PRICE = 1000; | ||
|
||
private final LottoBalls lottoBalls; | ||
|
||
public LottoTicket(final LottoBalls lottoBalls) { | ||
this.lottoBalls = lottoBalls; | ||
} | ||
|
||
public List<LottoBall> getLottoBalls() { | ||
List<LottoBall> lottoBalls = this.lottoBalls.getLottoBalls(); | ||
return Collections.unmodifiableList(lottoBalls); | ||
} | ||
|
||
public LottoRank findMatchesNumber(WinningLotto winningLotto) { | ||
return winningLotto.winningMatchCount(lottoBalls); | ||
} | ||
} |
Oops, something went wrong.