-
Notifications
You must be signed in to change notification settings - Fork 362
Step4 - 로또 (수동) #974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Step4 - 로또 (수동) #974
Changes from all commits
d008b10
dffd018
2273de6
e28951c
8dfcb45
9b5f054
a0698e5
4578453
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,3 +1,24 @@ | ||||||
| package lotto.data | ||||||
|
|
||||||
| data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) | ||||||
| data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { | ||||||
|
|
||||||
| init { | ||||||
| validateWinningLotto() | ||||||
| } | ||||||
|
|
||||||
| fun countMatchingNumbers(lotto: Lotto): Int { | ||||||
| return this.lotto.selectNumbers.intersect(lotto.selectNumbers).size | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 모든 로직을 작성할때 dot(.)이 몇 개인지 체크해보는것도 좋을 것 같아요. 개인적으로는 Stream API와 같이 중간 오퍼레이터들이 있는 지연 연산되는 특수한 경우를 제외하고는 2개 이상의 dot(.)이 있는경우 내가 지금 이 객체의 속살을 모두 꺼내서 요리를 하는게 아닌가? 고민해볼 수 있어요.
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| fun hasBonusNumber(lotto: Lotto): Boolean { | ||||||
| return lotto.selectNumbers.contains(bonusNumber) | ||||||
| } | ||||||
|
|
||||||
| private fun validateWinningLotto() { | ||||||
| validateDuplicationBonusNumber() | ||||||
| } | ||||||
|
|
||||||
| private fun validateDuplicationBonusNumber() { | ||||||
| require(!lotto.selectNumbers.contains(bonusNumber)) { "당첨 번호 구성과 보너스 번호가 중복됩니다." } | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package lotto.domain | ||
|
|
||
| import lotto.data.LottoRanking | ||
|
|
||
| object LottoCalculator { | ||
|
|
||
| private const val GAME_COST = 1000 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보통 상품의 가격은 상품에서 가지고 있죠. |
||
|
|
||
| fun calculateWinningRate(cash: Int, winningStatus: Map<LottoRanking, Int>): Float { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. map자료구조에서 열거타입을 사용한다면 EnumMap을 고려해보면 좋을 것 같아요. |
||
| val totalPrice = winningStatus.toList().sumOf { it.first.findPrize(it) } | ||
|
|
||
| return totalPrice / cash.toFloat() | ||
| } | ||
|
|
||
| fun getTimes(cash: Int): Int { | ||
| return cash / GAME_COST | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package lotto.data | ||
|
|
||
| import org.assertj.core.api.Assertions.assertThat | ||
| import org.junit.jupiter.api.Test | ||
|
|
||
| class WinningLottoTest { | ||
|
|
||
| @Test | ||
| fun `당첨 번호와 일치하는 번호 수 반환`() { | ||
| // given : 당첨로또와 로또를 받는다. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 주석에 행위에 대한 설명을 작성하는건 외부에 의한 요인으로 인한 변경점이 있어서 함수 시그니처로 나타내기 부족한 경우처럼 필수적인 경우가 아니라면 비권장드립니다. 컴파일시 체크할 수 있는 항목도 아니기에 기능변경이 일어나거나 관련 시그니처가 변경될때 해당 개발자가 직접 체크하지 않는한 놓치게 될 수 있고, 이로인해 시그니처와 주석이 달라지게되면서 차후 새로운 개발자는 혼동을 겪을 수 있습니다. 즉 가독성이 떨어지게 되는 것이죠. |
||
| val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) | ||
| val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) | ||
|
|
||
| // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] | ||
| val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) | ||
| val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) | ||
|
|
||
| // when : 검증 로직을 실행한다. | ||
| val actual1 = winningLotto.countMatchingNumbers(lotto1) | ||
| val actual2 = winningLotto.countMatchingNumbers(lotto2) | ||
|
|
||
| // then : 일치하는 번호의 개수를 반환한다. | ||
| assertThat(actual1).isEqualTo(5) | ||
| assertThat(actual2).isEqualTo(6) | ||
| } | ||
|
|
||
| @Test | ||
| fun `보너스 번호 일치 검증`() { | ||
| // given : 당첨로또와 로또를 받는다. | ||
| val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) | ||
| val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) | ||
|
|
||
| // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] | ||
| val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) | ||
| val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) | ||
|
|
||
| // when : 보너스 번호 일치 검증 로직을 호출한다. | ||
| val actual1 = winningLotto.hasBonusNumber(lotto1) | ||
| val actual2 = winningLotto.hasBonusNumber(lotto2) | ||
|
|
||
| // then : | ||
| assertThat(actual1).isTrue() | ||
| assertThat(actual2).isFalse() | ||
| } | ||
|
|
||
| @Test | ||
| fun `보너스 번호 중복 검증`() { | ||
| // given : 당첨 번호로 구성된 로또와 이와 중복되는 보너스 번호를 받는다. | ||
| val lotto = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) | ||
| val bonusLottoNumber = LottoNumber.from(6) | ||
|
|
||
| // when : | ||
| val actual = runCatching { WinningLotto(lotto, bonusLottoNumber) }.exceptionOrNull() | ||
|
|
||
| // then : | ||
| assertThat(actual).isInstanceOf(IllegalArgumentException::class.java) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package lotto.domain | ||
|
|
||
| import lotto.data.LottoRanking | ||
| import org.assertj.core.api.Assertions.assertThat | ||
| import org.junit.jupiter.api.Test | ||
|
|
||
| class LottoCalculatorTest { | ||
| @Test | ||
| fun `로또 수익율 반환 로직`() { | ||
| // given : 구매한 로또의 통계와 구매 금액을 받는다. | ||
| // 총 당첨금 5천원 | ||
| val cash = 100000 | ||
| val winningStatus = mutableMapOf<LottoRanking, Int>() | ||
| winningStatus[LottoRanking.FifthPlace] = 1 | ||
|
|
||
| // when : 구매 금액 대비 당첨 금액에 대한 수익률은 요청한다. | ||
| val actual: Float = LottoCalculator.calculateWinningRate(cash, winningStatus) | ||
|
|
||
| // then : 수익률이 반환된다. | ||
| assertThat(actual).isEqualTo(0.05f) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정적 팩토리 함수에서 직접 2등인지 보너스 번호를 비교해야할까요? 이런 특별한 플래그들에 대한 조건들이 보너스 넘버가 끝이 아니라 계속 해서 추가되면 매번 이 함수에 조건들이 추가되야 할 것 같은데, 괜찮을까요?