Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 13 additions & 5 deletions src/main/kotlin/controller/LottoApp.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package controller

import model.lotto.LottoCount
import model.lotto.LottoGameGenerator
import model.lotto.LottoNumber
import model.lotto.LottoNumbers
import model.lotto.LottoTickets
Expand Down Expand Up @@ -50,12 +49,10 @@ class LottoApp(private val inputView: InputView, private val outputView: OutputV
return LottoCount.of(manualCount, money)
}

// FIXME: 테스트 용이성이나 객체지향 관점에서 Ticket 은 LottoTicket 이 직접 생성해줘야하지 않을까요?
private fun generateLottoTicket(lottoCount: LottoCount): LottoTickets {
val manualNumbers = requestManualLottoNumbers(lottoCount.manualCount)
val manualGames = LottoGameGenerator.generate(manualNumbers)
val autoGames = LottoGameGenerator.generate(lottoCount.autoCount)
return LottoTickets.createWithGames(manualGames + autoGames)
val autoNumbers = requestAutoLottoNumbers(lottoCount.autoCount)
return LottoTickets.of(manualNumbers, autoNumbers)
}

private fun requestManualLottoNumbers(manualCount: Int): List<LottoNumbers> {
Expand All @@ -64,4 +61,15 @@ class LottoApp(private val inputView: InputView, private val outputView: OutputV
LottoNumbers.from(inputView.requestLottoNumber())
}
}

private fun requestAutoLottoNumbers(autoCount: Int): List<LottoNumbers> {
val allPossibleNumbers = (1..45).toList()
return List(autoCount) {
val selectedNumbers = allPossibleNumbers
.shuffled()
.take(6)
.sorted()
LottoNumbers.from(selectedNumbers)
}
}
}
37 changes: 3 additions & 34 deletions src/main/kotlin/model/lotto/LottoGame.kt
Original file line number Diff line number Diff line change
@@ -1,41 +1,10 @@
package model.lotto

enum class TicketType {
Manual,
Auto,
}

data class LottoGame(
val numbers: LottoNumbers,
val type: TicketType,
) {
companion object {
fun of(
numbers: LottoNumbers,
type: TicketType,
): LottoGame {
return LottoGame(numbers, type)
}
}
sealed class LottoGame(val numbers: LottoNumbers) {
class Manual(manualNumbers: LottoNumbers) : LottoGame(manualNumbers)
class Auto(autoNumbers: LottoNumbers) : LottoGame(autoNumbers)
Comment on lines +3 to +5
Copy link
Contributor

Choose a reason for hiding this comment

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

패턴 매칭 😀

Copy link
Member Author

Choose a reason for hiding this comment

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

이런 방법을 패턴 매칭이라 하는군요!! 😲

Copy link
Member

Choose a reason for hiding this comment

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

저도 새로운거 알아갑니다~


override fun toString(): String {
return numbers.toString()
}
}

object LottoGameGenerator {
fun generate(count: Int): List<LottoGame> {
val allPossibleNumbers = (1..45).toList()
return List(count) {
val selectedNumbers = allPossibleNumbers.shuffled().take(6).sorted()
val lottoNumbers = LottoNumbers.from(selectedNumbers)
LottoGame.of(lottoNumbers, TicketType.Auto)
}
}

fun generate(manualNumbers: List<LottoNumbers>): List<LottoGame> {
return manualNumbers.map { lottoNumbers ->
LottoGame.of(lottoNumbers, TicketType.Manual)
}
}
}
10 changes: 6 additions & 4 deletions src/main/kotlin/model/lotto/LottoTicket.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package model.lotto

internal const val REQUIRED_LEAST_ONE_GAME = "최소 한 게임 이상 포함되어야 합니다."
internal const val REQUIRED_MAXIMUM_FIVE_GAME = "최대 다섯 게임만 포함될 수 있습니다."

class LottoTicket(val games: List<LottoGame>) {
companion object {
fun of(games: List<LottoGame>): LottoTicket {
return LottoTicket(games)
}
init {
require(games.isNotEmpty()) { REQUIRED_LEAST_ONE_GAME }
require(games.size < 6) { REQUIRED_MAXIMUM_FIVE_GAME }
}

override fun toString(): String {
Expand Down
10 changes: 4 additions & 6 deletions src/main/kotlin/model/lotto/LottoTickets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ class LottoTickets(
val elements: List<LottoTicket>,
) {
companion object {
fun of(elements: List<LottoTicket>): LottoTickets {
return LottoTickets(elements)
}

fun createWithGames(elements: List<LottoGame>): LottoTickets {
val tickets = elements.chunked(5).map { LottoTicket.of(it) }
fun of(manualNumbers: List<LottoNumbers>, autoNumbers: List<LottoNumbers>): LottoTickets {
val manualGames = manualNumbers.map { LottoGame.Manual(it) }.toList()
val autoGames = autoNumbers.map { LottoGame.Auto(it) }.toList()
val tickets = (manualGames + autoGames).chunked(5).map { LottoTicket(it) }
Comment on lines +9 to +11
Copy link
Contributor

Choose a reason for hiding this comment

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

아름답습니다...

Copy link
Member

Choose a reason for hiding this comment

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

이게 언어지...

return LottoTickets(tickets)
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/main/kotlin/view/OutputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package view

import model.lotto.LottoGame
import model.lotto.LottoTickets
import model.lotto.TicketType

internal const val INPUT_MONEY_MESSAGE = "구입금액을 입력해 주세요."
internal const val INPUT_MANUAL_INPUT_MESSAGE = "수동으로 구매할 로또 게임 수를 입력해 주세요."
Expand Down Expand Up @@ -33,8 +32,8 @@ class OutputView {
}

private fun printLottoGames(lottoGames: List<LottoGame>) {
val manualGames = lottoGames.filter { it.type == TicketType.Manual }
val autoGames = lottoGames.filter { it.type == TicketType.Auto }
val manualGames = lottoGames.filterIsInstance<LottoGame.Manual>()
val autoGames = lottoGames.filterIsInstance<LottoGame.Auto>()
println("수동으로 ${manualGames.size}게임, 자동으로 ${autoGames.size}게임을 구매하셨습니다.")
if (manualGames.isNotEmpty()) {
println("수동으로 구매한 로또 번호")
Expand Down
18 changes: 18 additions & 0 deletions src/test/kotlin/model/FixtureGenerator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package model

import model.lotto.LottoGame
import model.lotto.LottoNumbers

fun generateFixtureLottoGames(count: Int): List<LottoGame> {
if (count == 0) {
return emptyList()
}

return List(count) {
val selectedNumbers = (1..45).toList()
.shuffled()
.take(6)
.sorted()
LottoGame.Auto(LottoNumbers.from(selectedNumbers))
}
}
29 changes: 0 additions & 29 deletions src/test/kotlin/model/lotto/LottoGameGeneratorTest.kt

This file was deleted.

22 changes: 8 additions & 14 deletions src/test/kotlin/model/lotto/LottoGameTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,18 @@ import io.kotest.matchers.shouldBe

class LottoGameTest : FreeSpec(
{
"LottoGame 생성" - {
"주어진 LottoNumbers 와 TicketType 을 가진 LottoGame 을 반환" {
val numbers = LottoNumbers.from(listOf(1, 2, 3, 4, 5, 6))
val ticketType = TicketType.Manual
val ticket = LottoGame.of(numbers, ticketType)
"ManualLotto 생성" {
val numbers = LottoNumbers.from(listOf(1, 2, 3, 4, 5, 6))
val ticket = LottoGame.Manual(numbers)

ticket.numbers shouldBe numbers
ticket.type shouldBe ticketType
}
ticket.numbers shouldBe numbers
}

"LottoGame 출력" - {
"LottoGame 의 numbers 필드를 문자열화 하여 반환" {
val numbers = LottoNumbers.from(listOf(1, 2, 3, 4, 5, 6))
val ticket = LottoGame.of(numbers, TicketType.Manual)
"AutoLotto 출력" {
val numbers = LottoNumbers.from(listOf(1, 2, 3, 4, 5, 6))
val ticket = LottoGame.Auto(numbers)

ticket.toString() shouldBe numbers.toString()
}
ticket.toString() shouldBe numbers.toString()
}
},
)
38 changes: 38 additions & 0 deletions src/test/kotlin/model/lotto/LottoTicketTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package model.lotto

import io.kotest.assertions.throwables.shouldThrowExactly
import io.kotest.core.spec.style.FreeSpec
import io.kotest.matchers.shouldBe
import model.generateFixtureLottoGames

class LottoTicketTest : FreeSpec(
{
"LottoTicket을 생성할 때" - {
"1개의 로또 게임이 포함 될 수 있다." - {
val count = 1
val ticket = LottoTicket(generateFixtureLottoGames(count))
ticket.games.size shouldBe count
}

"5개의 로또 게임이 포함 될 수 있다." - {
val count = 5
val ticket = LottoTicket(generateFixtureLottoGames(count))
ticket.games.size shouldBe count
}

"로또 게임이 없으면 안된다." - {
val games = generateFixtureLottoGames(0)
println(games)
shouldThrowExactly<IllegalArgumentException> {
LottoTicket(emptyList())
}.message shouldBe REQUIRED_LEAST_ONE_GAME
}

"로또 게임이 6개 이상 포함되면 안된다." - {
shouldThrowExactly<IllegalArgumentException> {
LottoTicket(generateFixtureLottoGames(6))
}.message shouldBe REQUIRED_MAXIMUM_FIVE_GAME
}
}
},
)
10 changes: 0 additions & 10 deletions src/test/kotlin/model/lotto/LottoTicketsTest.kt

This file was deleted.