Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ed22ad5
[step4] docs: 기능 목록 정리
bong6981 Dec 2, 2023
ea2d901
[step4] feat: 21점이면 더이상 카드를 받지 못하도록 변경
bong6981 Dec 2, 2023
d095226
[step3] chore: getDesiredAction -> desiredAction 네이밍 변경
bong6981 Dec 2, 2023
b1ebc8a
[step4] feat: 플레이어 이름을 식별자로 사용
bong6981 Dec 2, 2023
158af44
[step4] feat: 플레이어별 베팅 금액 저장
bong6981 Dec 2, 2023
c8eca31
[step4] feat: 베팅 금액에 따른 수익 계산 및 출력
bong6981 Dec 3, 2023
3d30c05
[step3] refactor: View를 보여줄지 말지는 ViewResultProcessor에서 처리
bong6981 Dec 3, 2023
5181cef
[step3] refactor: requireNotNul()을 활용
bong6981 Dec 3, 2023
fc1d9ae
[step3] refactor: step3 피드백 반영
bong6981 Dec 3, 2023
a4db3db
[step4] chore: 생성 로직을 앞단으로 이동
bong6981 Dec 6, 2023
780067a
[step4] feat: PlayerGameResult 의 player 접근제어자 -> private
bong6981 Dec 6, 2023
d95162a
[step4] test: DCI 패턴을 고려한 테스트 이름 수정
bong6981 Dec 6, 2023
00f52f0
[step4] feat: 게임 승패는 BlackJackJudge에서 판단하도록 변경
bong6981 Dec 6, 2023
8bbefe0
[step4] feat: 블랙잭 여부는 BlackJackJudge에서 판단하도록 변경
bong6981 Dec 6, 2023
f96543d
[step4] chore: BUST_THRESHOLD 대신 BLACK_JACK_SCORE 사사용
bong6981 Dec 6, 2023
ebae7ee
[step4] feat: BetAmount 분리
bong6981 Dec 31, 2023
c66f8bf
[step4] chore: 가독성을 위한 코드 줄바꿈 변경
bong6981 Dec 31, 2023
02e8ce0
[step4] chore: 불필요한 let 사용 삭제
bong6981 Dec 31, 2023
25c8735
[step4] refactor: 의미 없는 BUST_SCORE 사용 삭제
bong6981 Dec 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 80 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,87 @@
- git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가한다.

### 기능 목록

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문서화 👍

게임 입력
- [x] 게임에 참여할 사람의 이름을 입력 받는다
InputView : 게임에 필요한 입력값을 입력 받는다
- 게임에 참여할 사람의 이름을 입력 받는다
- 쉼표 기준으로 분리한다
- 2명의 이름을 입력 받는다
- 참가자의 이름은 공백일 수 없다.
게임 세팅
- [x] 입력 받은 사람의 이름으로 참가자를 생성한다
- [x] 카드 52장 (1덱)을 세팅한다
- [x] 플레이어는 게임을 시작할 때 베팅 금액을 정해야 한다

InputProcessor : 입력 금액을 검증하고 도메인 레벨로 변환한다
- 게임에 참여할 사람의 이름을 처리한다
- 게임 참여자는 2명이여야 한다
- 게임 참여자의 이름은 서로 달라야 한다
- 게임 참여자 이름은 공백일 수 없다.
- [x] 베팅 금액을 처리한다
- 베팅 금액은 0보다 커야 한다

BlackJackGame : 게임을 진행한다
- distributor 가 dealEnd 가 될 때까지 카드 배분을 진행한다
- 각 카드 배분의 결과를 result 처리기에 넘긴다
- 초기 카드 배분자는 DealIntialCards()이다
- 카드 배분 횟수를 초과하면 종료시킨다
- 한 사람이 최대 가질 수 있는 카드 수 11장 ( Ace(1) * 4 + 2 * 4 + 3 * 3) : 배분 9번 진행
- 한 게임당 가질 수 있는 최대 카드 배분 횟수 : 초키 카드 배분 + 9번 진행 * 2 + 딜러 카드 배분 = 20

GameTable
- 딜러와 플레이어를 갖고 상호간의 카드 이동을 담당한다
- 배팅 보드를 가지고 게임이 끝나면 게임 결과로 베팅 결과를 산출한다

Players
- 플레이어를 관리하고 어떤 플레이어의 턴인지 관리한다
- 플레이어 이름으로 플레이어를 생성한다
- PlayerNames : 플레이어 이름 리스트
- [x] 각 플레이어는 다른 이름이어야 함

Dealer
- 카드 52장 (1덱)을 세팅한다
- 스페이스, 하트, 다이아, 클로버 4개의 각 문양이 2~10, jack, queen, king, ace 13장으로 구성
게임 진행
- 처음 카드 배분
- [x] 참가자와 딜러에게 각각 2장의 카드를 나눠 준다
- [x] 받은 카드를 출력한다
- 딜러의 카드는 한 장만 출력한다
- 플레이어 카드 배분
- [x] 참가자 중 1명에게 카드를 더 받을지 묻고, 참가자는 y 또는 n 으로 대답한다.
- [x] 참가자가 y를 입력하면 카드 한 장을 더 지급한다
- [x] 한 사람이 받은 카드를 계산했을 때 21을 넘는다면 더이상 카드를 받을 수 없다.
- [x] 참가자가 n을 입력하면 다른 참가자에게 턴이 넘어간다. 두번째 참가자라면 딜러에게 턴이 넘어간다
- [x] 참가자가 y, n을 입력하면 카드 지급 여부에 관계 없이 결과를 출력한다
- 딜러 카드 배분
- [x] 처음 받은 2장의 카드의 합이 16이하이면 1장의 카드를 받고, 17이상이면 카드를 받지 않는다
- [x] 딜러가 카드를 받았는지 여부를 출력한다
- 결과 출력
- [x] 게임이 종료되면 딜러와 플레이어의 카드 점수를 출력한다
- [x] 게임 최종 결과는 21을 넘지 않으면서, 21에 가까운 방식으로 계산한다
- 카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다.
- 승패 계산
- [x] 승패를 가른다
- 각 플레이어와 딜러의 승패를 가른다
- 버스트 : 21점 초과 / 푸시 : 딜러와 동점 (무승부)
- 딜러가 각각 딜러와 다 겨뤄 21에 더 가까운 사람이 승리한다
- 버스트시에는 점수가 0점이다
- 플레이어와 딜러가 둘 다 버스트라면 딜러가 승리한다
- 딜러와 플레이어가 버스트가 아니면서 동일 점수라면 무승부
- 가른 승패의 결과를 출력한다
- 게임 종료
- [x] 게임을 종료시킨다
- 카드 배분이 끝나면 (DistributionEnd) 게임을 종료시킨다
- 카드 배분 횟수를 초과하면 종료시킨다
- 한 사람이 최대 가질 수 있는 카드 수 11장 ( Ace(1) * 4 + 2 * 4 + 3 * 3) : 배분 9번 진행
- 한 게임당 가질 수 있는 최대 카드 배분 횟수 : 초키 카드 배분 + 9번 진행 * 2 + 딜러 카드 배분 = 20
- 자신의 카드 보유에 따라 hit or stand 를 반환한다
- 처음 받은 2장의 카드의 합이 16이하이면 1장의 카드를 받고, 17이상이면 카드를 받지 않는다

Player
- [x] 플레이어는 이름이 같으면 동일한 플레이어로 취급된다
- hitOrStand: 사용자의 의견에 따라 카드를 더 받을지(hit) 그만할지(stand)를 반환한다
- 사용자가 hit 를 요청했더라도 카드 점수가 21점 이상이면 stand 를 반환한다
- 딜러와의 점수를 비교해서 승패를 가를 수 있다
- 버스트 : 딜러 점수와 상관 없이 패
- 그 외 딜러보다 점수가 높으면 승, 같으면 무, 낮으면 패

BettingBoard : 베팅 보드
- [x] 플레이어별 베팅 금액을 저장
- [x] 게임이 종료되면 플레이어별 승패 결과에 따라 각 플레이어가 받을 금액을 결정한다
- 플레이어가 이겼을 때
- 블랙잭으로 이겼을 때 : 베팅금액 회수 + 베팅금액 * 1.5
- 일반 수로 이겼을 때 : 베팅금액 회수 + 베팅금액 * 1
- 무승부일 때 : 베팅금액 회수
- 졌을 때: 베팅금액 뺏김
- PlayerBet
- 플레이어의 베팅 금액과 받은 금액으로 최종 수익을 계산한다

DealInitialCards : 처음 카드 배분
- 참가자와 딜러에게 각각 2장의 카드를 나눠 준다

DealToPlayer
- 참가자 중 1명에게 카드를 더 받을지 묻고, 결과에 따라 카드를 지급한다
- 참가자가 hit 라면 카드 한 장을 더 지급한다
- 참가자가 stand 라면 다른 참가자에게 턴이 넘어간다. 두번째 참가자라면 딜러에게 턴이 넘어간다
- 참가자의 hit or stand 마다 배분 결과를 반환한다
- 참가자가 stand 였을 때 점수가 21점 이상이라면 시스템으로 인한 stand로 판별한다

DealToDealer
- 딜러의 카드 상태에 따라 hit or stand 를 조회하고 결과에 따라 카드를 지급한다
- 딜러까지 카드 배분이 끝나면 카드 배분을 종료한다

ResultProcessor
- 발생한 Result 이벤트에 따라 해당 이벤트를 알맞은 ResultHandler 에 전달한다
- DealToPlayerResult 인 경우 시스템상의 stand 라면 뷰에 결과를 전달하지 않는다

ViewResultProcessor
- 딜러의 카드는 한 장만 출력한다
- 게임이 종료되면 (GameResult 인 경우) 딜러와 플레이어의 카드 점수를 출력한다
- 베팅 결과를 최종 수익을 출력한다

GameResult
- 게임 최종 결과는 21을 넘지 않으면서, 21에 가까운 방식으로 계산한다
- 카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다.
3 changes: 3 additions & 0 deletions src/main/kotlin/blackjack/controller/InputProcessor.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package blackjack.controller

import blackjack.domain.Action
import blackjack.domain.batting.Amount
import blackjack.domain.player.Player
import blackjack.domain.player.PlayerNames

interface InputProcessor {
fun playerNames(): PlayerNames

fun playerBet(player: Player): Amount

fun playerAction(player: Player): Action
}
11 changes: 5 additions & 6 deletions src/main/kotlin/blackjack/controller/ResultProcessor.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package blackjack.controller

import blackjack.domain.result.Result
import blackjack.domain.result.distribution.DealEndResult
import blackjack.domain.result.distribution.DealInitialCardResult
import blackjack.domain.result.distribution.DealToDealerResult
import blackjack.domain.result.distribution.DealToPlayerResult
import blackjack.domain.result.game.GameResult
import blackjack.domain.result.game.GameEndResult

class ResultProcessor {
fun handle(result: Result) {
when (result) {
is DealInitialCardResult -> ViewResultProcessor.drawInitialDistribution(result)
is DealToPlayerResult -> {
if (result.isSystemStand) return
ViewResultProcessor.drawPlayerState(result)
}
is DealToPlayerResult -> ViewResultProcessor.drawPlayerState(result)
is DealEndResult -> {}
is DealToDealerResult -> ViewResultProcessor.drawDealerState(result)
is GameResult -> ViewResultProcessor.drawGameResult(result)
is GameEndResult -> ViewResultProcessor.drawGameResult(result)
}
}
}
9 changes: 8 additions & 1 deletion src/main/kotlin/blackjack/controller/ViewInputProcessor.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blackjack.controller

import blackjack.domain.Action
import blackjack.domain.batting.Amount
import blackjack.domain.player.Player
import blackjack.domain.player.PlayerNames
import blackjack.view.dto.PlayerNameDto
Expand All @@ -10,11 +11,17 @@ class ViewInputProcessor : InputProcessor {
override fun playerNames(): PlayerNames =
InputView.playerNames().let(PlayerNames::from)

override fun playerBet(player: Player): Amount =
InputView.playerBet(player.nameDto())
.let { Amount.betAmount(it.toInt()) }

override fun playerAction(player: Player): Action {
val action = InputView.playerAction(player.let(PlayerNameDto::from))
val action = InputView.playerAction(player.nameDto())
return toPlayerAction(action)
}

private fun Player.nameDto(): PlayerNameDto = this.let(PlayerNameDto::from)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let에 생성자 제가 조금 설명을 러프하게 드렸었는데요. 생성자를 사용해도 되는 것에 대해서 굳이 let을 사용하지 않는게 좋을 것 같다라는 것이 제 의견이었습니다.

this.let(PlayerNameDto::from)
PlayerNameDto.from(this)

에서 읽히는 과정을 본다면 let은 this를 let으로 처리하는데 이때 from을 사용하여 생성한다가 될 것이고, 아래는 this를 from을 사용하여 생성한다로 읽히게 되어요. 결국 let은 추가적인 재처리를 위한 용도로 사용되는데 생성자를 재처리하는 것이 로직적인 문제는 없으나 의미가 없는 tailing 구문이 발생하는 것과 다름이 없으므로 큰 복잡한 로직 없이 생성을 한다면 let을 제거하는 것이 좋다라는 생각이에요.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음.. 제가 아직 명확하게 이해하지 못한 것 같습니다.

  • 말씀주신 예시에서는 let 을 쓰지 않는 것이 더 가독성도 좋아 보입니다.

만약, 아래 예시에서는

InputParser.intoPlayerNames(readInput())
readInput().let(InputParser::intoPlayerNames)
  • 아래 구문이 개인적으로는 가독성이 더 좋아보입니다. 이 역시 불필요한 tailing 구문으로 볼 수 있긴 하겠지만, 왼쪽에서 오른쪽으로 읽을 경우 input 을 읽어와서 파싱한다로 좀 더 자연스럽지 않나 라는 생각이 드는데요.
  • 혹시 이런 경우에도 let 사용을 지양하시는 것일까요?
 return when {
                ranks.hasAce().not() -> score
                score + ACE_BONUS_SCORE > MAX_SCORE -> score
                else -> score + ACE_BONUS_SCORE
            }.let(::HandScore)

이런 케이스에서도 HandScore 을 생성하다는 로직 보다는 어떻게 점수 계산이 되는지 when { } 안의 로직이 먼저 읽혀야 한다고 생각해서 여기는 let 사용이 낫지 않나 라는 생각이 듭니다!

그러나 위 2 케이스 모두 리뷰어님이 말씀주신 큰 복잡한 로직 없이 생성하는 로직인 것 같습니다. 이에 대해서도 같은 생각이신지 궁금합니다!


private fun toPlayerAction(action: String): Action = when (action) {
"y" -> Action.HIT
"n" -> Action.STAND
Expand Down
38 changes: 26 additions & 12 deletions src/main/kotlin/blackjack/controller/ViewResultProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package blackjack.controller
import blackjack.domain.result.distribution.DealInitialCardResult
import blackjack.domain.result.distribution.DealToDealerResult
import blackjack.domain.result.distribution.DealToPlayerResult
import blackjack.domain.result.game.GameResult
import blackjack.domain.result.game.GameEndResult
import blackjack.view.dto.DealerCardsResultDto
import blackjack.view.dto.DealerHitDto
import blackjack.view.dto.FinalDealerStateDto
import blackjack.view.dto.FinalPlayerStateDto
import blackjack.view.dto.DealerProfitDto
import blackjack.view.dto.PlayerCardsResultDto
import blackjack.view.dto.PlayerDto
import blackjack.view.dto.PlayerProfitDto
import blackjack.view.output.OutputView

object ViewResultProcessor {
Expand All @@ -18,6 +20,7 @@ object ViewResultProcessor {
}

fun drawPlayerState(result: DealToPlayerResult) {
if (result.isSystemStand) return
val dto = result.player.let { PlayerDto(it.name.value, it.hand.cards) }
OutputView.drawPlayerCurrentState(dto)
}
Expand All @@ -26,15 +29,26 @@ object ViewResultProcessor {
OutputView.drawDealerHitStatus(DealerHitDto(result.isHit))
}

fun drawGameResult(result: GameResult) {
fun drawGameResult(result: GameEndResult) {
drawCardResult(result)
drawProfitResult(result)
}

private fun drawCardResult(result: GameEndResult) {
val dealerDto =
DealerCardsResultDto(result.dealerHand.cards, result.dealerScore.cardScore)
val playersDto = result.playerResults.map {
PlayerCardsResultDto(it.name.value, it.hand.cards, it.score.cardScore)
}
OutputView.drawCardsResults(dealerDto, playersDto)
}

private fun drawProfitResult(result: GameEndResult) {
val dealerDto =
result.dealerResults.let {
FinalDealerStateDto(it.dealer.hand.cards, it.dealer.score.cardScore, it.status)
}
val playersDto =
result.playersResult.map {
FinalPlayerStateDto(it.player.name.value, it.player.hand.cards, it.player.score.cardScore, it.status)
}
OutputView.drawFinalResults(dealerDto, playersDto)
DealerProfitDto(result.dealerProfit.value.toString())
val playersDto = result.playerResults.map {
PlayerProfitDto(it.name.value, it.profit.value.toString())
}
OutputView.drawProfitResults(dealerDto, playersDto)
}
}
24 changes: 14 additions & 10 deletions src/main/kotlin/blackjack/domain/BlackJackGame.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@ package blackjack.domain

import blackjack.controller.InputProcessor
import blackjack.controller.ResultProcessor
import blackjack.domain.batting.BetBoard
import blackjack.domain.distirbution.CardDistributor
import blackjack.domain.distirbution.DealEnd
import blackjack.domain.distirbution.DealInitialCards
import blackjack.domain.player.Players
import blackjack.domain.result.Result
import blackjack.domain.result.distribution.DealEndResult
import blackjack.domain.result.game.GameEndResult

class BlackJackGame(
private val inputProcessor: InputProcessor,
private val resultProcessor: ResultProcessor = ResultProcessor(),
inputProcessor: InputProcessor,
players: Players = Players.of(inputProcessor.playerNames()) { player -> inputProcessor.playerAction(player) },
private val resultProcessor: ResultProcessor,
) {
var dealCards: CardDistributor = DealInitialCards(
GameTable(
Dealer(),
Players.of(inputProcessor.playerNames()) { player -> inputProcessor.playerAction(player) }
),
)

var dealCards: CardDistributor = DealInitialCards(GameTable(players))
private set

val betBoard: BetBoard = BetBoard.of(players) { player -> inputProcessor.playerBet(player) }

fun run() {
var distributionCount = 0
while (dealCards !is DealEnd && distributionCount < MAX_DISTRIBUTION_COUNT) {
Expand All @@ -40,8 +42,10 @@ class BlackJackGame(
}

private fun endDeal() {
val result = dealCards.deal()
emitResult(result)
val dealEndResult = dealCards.deal() as? DealEndResult
?: throw IllegalArgumentException("배분이 종료되지 않았습니다")
betBoard.closeBetting(dealEndResult)
emitResult(GameEndResult.of(dealEndResult, betBoard))
}

companion object {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/blackjack/domain/GameTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import blackjack.domain.player.Player
import blackjack.domain.player.Players

data class GameTable(
val dealer: Dealer,
val players: Players,
val dealer: Dealer = Dealer(),
) {
val isLastPlayerTurn: Boolean
get() = players.isLastTurn
Expand Down
24 changes: 24 additions & 0 deletions src/main/kotlin/blackjack/domain/batting/Amount.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package blackjack.domain.batting

import java.math.BigDecimal

data class Amount(
val value: BigDecimal,
) : Comparable<Amount> {

operator fun plus(other: Amount): Amount = value.plus(other.value).let(::Amount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
operator fun plus(other: Amount): Amount = value.plus(other.value).let(::Amount)
operator fun plus(other: Amount): Amount = Amount(value.plus(other.value))

let으로 변환하는 방법도 있겠지만 단순히 Amount에 대한 생성이 목표라면 생성자를 붙여주는것이 가독성이 더 높을 것 같아요.

결국 Amount에 대한 생성을 목표로하기 때문에 생성자를 사용하지 않을 이유도 없고, let(stream) 처리가 추가됨으로써 가독성이 오히려 떨어질 수도 있거든요.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오른쪽으로 쭉 읽으며 의미가 이해 된다고 생각했는데, Amount 생성자를 붙여주는 것이 더 가독성이 좋군요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a4db3db 에서 반영했습니다!

operator fun times(count: Int): Amount = value.times(count.toBigDecimal()).let(::Amount)

operator fun times(count: BigDecimal): Amount =
Amount(value * count)
override fun compareTo(other: Amount): Int =
this.value.compareTo(other.value)

companion object {
val ZERO = Amount(BigDecimal.ZERO)
fun betAmount(amount: Int): Amount {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Int로 들어온 value를 단순히 BigDecimal로 변환하고 있기 때문에 betAmount 보다는 Amount를 생성한다는 의미가 더 어울리지 않을까요?
  2. 정적팩토리메소드를 사용하고 있다면 생성자를 private하게 해주어도 되지 않을까요?
  3. 혹은 정적팩토리메소드를 사용하지 않고 부생성자에서 처리하는건 어떨까요? 이정도의 타입을 변화하는 로직만 존재한다면 부생성자를 추가해도 충분할 것 같아보여서요.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Amount 는 단순 금액의 의미를 나타냅니다. Amount 자체는 0이 될 수 있습니다 ( 플레이어의 수령 금액 등 )
  • betAmount 는 Amount 중 베팅 금액에 대한 의미를 나타내기 때문에 팩토리 메서드로 분리해 검증했습니다
    해서 베팅금액에 대한 정적 팩토리 메서드를 따로 정의했습니다.!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BetAmount(val value: Amount) 로 분리하지 않은 이유는 단순 생성시에서 값 체크만 BetAmount 로서의 기능을 한다고 생각해서 정적 팩토리 메서드로 검증을 하도록 했습니다!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀하신대로의 Amount가 0이 될 수 있다면 음수를 검증하는 validation은 Amount에서 필요해보입니다.
(반영하지 않으셔도 됩니다.) Amount가 단순 금액을 의미하고, "배팅 금액"은 금액에서 배팅이라는 비즈니스로직이 들어간다면 오히려 분리하는 것이 어떨까하네요. 개인적으로는 betAmount으로 호출의 의도하여도, 그 파라미터나 필드가 Amount 생성자를 통해서 생성하여 사용하게 된다면을 가정해보면 원하는 객체에 대한 생성 안전성이 떨어져보입니다.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BetAmount 로 이를 분리했습니다!

require(amount > 0) { "베팅 금액은 0보다 커야 합니다" }
return Amount(amount.toBigDecimal())
}
}
}
Loading