Skip to content
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 #1003

Open
wants to merge 8 commits into
base: gongwho
Choose a base branch
from
35 changes: 28 additions & 7 deletions src/main/kotlin/lotto/LottoSimulator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package lotto
import lotto.domain.LottoPurchaseOrder
import lotto.domain.LottoResult
import lotto.domain.LottoTicket
import lotto.provider.ticket.AutoTicketProvider
import lotto.provider.ticket.LottoTicketsProvider
import lotto.domain.LottoTickets
import lotto.domain.RankResult
import lotto.generator.ticket.ActualLottoShop
import lotto.generator.ticket.LottoShop
import lotto.view.InputView
import lotto.view.ResultView
import lotto.view.UserInputView
Expand All @@ -13,16 +15,16 @@ class LottoSimulator(
private val inputView: InputView,
private val resultView: ResultView,
) {
fun simulate(lottoTicketsProvider: LottoTicketsProvider): LottoResult {
fun simulate(lottoShop: LottoShop): LottoResult {
val purchaseOrder = LottoPurchaseOrder(
budget = inputView.getBudget(),
ticketPrice = LottoTicket.PRICE,
)

val lottoTickets = lottoTicketsProvider.provide(purchaseOrder.ticketCount)
inputView.printPurchasedLotto(lottoTickets)
val lottoTickets = generateLottoTickets(lottoShop, purchaseOrder.ticketCount)

val winningNumber = inputView.getWinningNumber()

val lottoResult = lottoTickets.getRankResult(winningNumber)

val result = LottoResult(
Expand All @@ -31,15 +33,34 @@ class LottoSimulator(
remainder = purchaseOrder.remainder
)

printLottoResult(lottoResult, result)

return result
}

private fun printLottoResult(lottoResult: RankResult, result: LottoResult) {
resultView.printRankResults(lottoResult)
resultView.printResult(result)
return result
}

private fun generateLottoTickets(lottoShop: LottoShop, ticketCount: Int): LottoTickets {
val manualLottoCount = inputView.getManualLottoCount()

val manualTickets = if (manualLottoCount != 0) {
inputView.printManualLottoInputString()

Choose a reason for hiding this comment

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

단순히 print를 실행하기보단,
함수에게 책임을주고, 행위를 위임해보면 어떨까요?

LottoSimulator가 하나씩 print에 관여하기보다, inputView에게 메세지를 전달해보아요!
inputView.getManualNumbers(manualLottoCount)

Copy link
Author

Choose a reason for hiding this comment

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

이 부분은 view 의 역할과 lotto shop 의 역할을 어디까지로 설정할 지 고민이 좀 되는 부분이네요 ㅎㅎ 일단 가장 적절해 보이는 방식으로 작성해 보겠습니다!

lottoShop.provideManualTickets(manualLottoCount)
} else LottoTickets(listOf())

val autoTickets = lottoShop.provideAutoTickets(ticketCount - manualLottoCount)
inputView.printPurchasedLotto(autoLottoTickets = autoTickets, manualLottoTickets = manualTickets)

return LottoTickets(manualTickets.lottoTicketList + autoTickets.lottoTicketList)
}

Choose a reason for hiding this comment

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

LottoSimulator내에서 계산하기보단,
LottoShop에게 위임하는 구조는 어덜까요?
manualTickets와 budget 만 부여하면, 내부적으로 알아서 로또를 생성해줄수 있지 않을까요?
(이미 생성된 LottoPurchaseOrder 객체를 활용해서 전달할수도 있을거같아요 )

}

fun main() {
LottoSimulator(
UserInputView(),
ResultView()
).simulate(lottoTicketsProvider = AutoTicketProvider)
).simulate(lottoShop = ActualLottoShop)
}
7 changes: 0 additions & 7 deletions src/main/kotlin/lotto/domain/ManualTicketProvideStrategy.kt

This file was deleted.

8 changes: 8 additions & 0 deletions src/main/kotlin/lotto/generator/ticket/ActualLottoShop.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package lotto.generator.ticket

import lotto.domain.LottoTickets

object ActualLottoShop : LottoShop {
override fun provideAutoTickets(ticketCount: Int): LottoTickets = AutoTicketGenerator.create(ticketCount)
override fun provideManualTickets(ticketCount: Int): LottoTickets = ManualTicketGenerator.create(ticketCount)

Choose a reason for hiding this comment

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

AutoTicketGenerator, ManualTicketGenerator를 싱글턴으로 접근하는구조네요!
싱글턴 패턴은 자주 사용되는 패턴이지만, 잘못사용되면 객체간 결합도를 높여주게 되는 현상이 있어요

Suggested change
object ActualLottoShop : LottoShop {
override fun provideAutoTickets(ticketCount: Int): LottoTickets = AutoTicketGenerator.create(ticketCount)
override fun provideManualTickets(ticketCount: Int): LottoTickets = ManualTicketGenerator.create(ticketCount)
class ActualLottoShop(
autoTicketGenerator: TicketGenerator,
manualTicketGenerator: lTicketGenerator
) : LottoShop {
override fun provideAutoTickets(ticketCount: Int): LottoTickets = autoTicketGenerator.create(ticketCount)
override fun provideManualTickets(ticketCount: Int): LottoTickets = manualTicketGenerator.create(ticketCount)

위 처럼 바꾼 코드랑은 어떤점이 다를까요? 고민해보시면 좋을거같아요!

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package lotto.domain
package lotto.generator.ticket

import lotto.provider.ticket.TicketProvideStrategy
import lotto.domain.LottoNumber
import lotto.domain.LottoTicket
import lotto.domain.LottoTickets

object AutoTicketProvideStrategy : TicketProvideStrategy {
object AutoTicketGenerator : TicketGenerator {
private val preGeneratedLottoNumbers = (LottoNumber.validNumberRange)
.map { LottoNumber(it) }
override fun provide(ticketCount: Int): LottoTickets {
override fun create(ticketCount: Int): LottoTickets {
val tickets = List(ticketCount) {
LottoTicket(
preGeneratedLottoNumbers
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/lotto/generator/ticket/LottoShop.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package lotto.generator.ticket

import lotto.domain.LottoTickets

interface LottoShop {
fun provideAutoTickets(ticketCount: Int): LottoTickets
fun provideManualTickets(ticketCount: Int): LottoTickets
}

interface TicketGenerator {
fun create(ticketCount: Int): LottoTickets
}
16 changes: 16 additions & 0 deletions src/main/kotlin/lotto/generator/ticket/ManualTicketGenerator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lotto.generator.ticket

import lotto.domain.LottoNumber
import lotto.domain.LottoTicket
import lotto.domain.LottoTickets

object ManualTicketGenerator : TicketGenerator {
override fun create(ticketCount: Int): LottoTickets {
val lottoTicketList = mutableListOf<LottoTicket>()
repeat(ticketCount) {
val lottoTicket = LottoTicket(readln().trim().split(",").map { it.toInt() }.map { LottoNumber(it) })

Choose a reason for hiding this comment

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

TicketGenerator는 domain 로직이라고 볼수도 있을거같아요,
생성로직과 View관련 기능은 분리해보면 어떨까요?

lottoTicketList.add(lottoTicket)
}
return LottoTickets(lottoTicketList)
}
}
8 changes: 0 additions & 8 deletions src/main/kotlin/lotto/provider/ticket/AutoTicketProvider.kt

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/kotlin/lotto/provider/ticket/LottoTicketsProvider.kt

This file was deleted.

6 changes: 5 additions & 1 deletion src/main/kotlin/lotto/view/InputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ interface InputView {

fun getWinningNumber(): WinningNumber

fun printPurchasedLotto(lottoTickets: LottoTickets)
fun printPurchasedLotto(autoLottoTickets: LottoTickets, manualLottoTickets: LottoTickets)

fun getManualLottoCount(): Int

fun printManualLottoInputString()
}
20 changes: 17 additions & 3 deletions src/main/kotlin/lotto/view/UserInputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,28 @@ class UserInputView : InputView {
)
}

override fun printPurchasedLotto(lottoTickets: LottoTickets) {
lottoTickets.lottoTicketList.forEach { ticket ->
override fun printPurchasedLotto(autoLottoTickets: LottoTickets, manualLottoTickets: LottoTickets) {
println("수동으로 ${manualLottoTickets.lottoTicketList.size}, 자동으로 ${autoLottoTickets.lottoTicketList.size} 개를 구매했습니다.")
manualLottoTickets.print()
autoLottoTickets.print()
}

override fun getManualLottoCount(): Int {
println("수동으로 구매할 로또 수를 입력해 주세요.")
return readln().trim().toInt()
}

override fun printManualLottoInputString() {
println("수동으로 구매할 번호를 입력해 주세요.")
}

private fun LottoTickets.print() {
lottoTicketList.forEach { ticket ->
println(
ticket.lottoNumberList.map { number ->
number.value
}
)
}
println("${lottoTickets.lottoTicketList.size} 개를 구매했습니다.")
}
}
16 changes: 8 additions & 8 deletions src/test/kotlin/lotto/LottoAutoTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import io.kotest.matchers.shouldBe
import lotto.domain.LottoNumber
import lotto.domain.LottoTicket
import lotto.domain.LottoTickets
import lotto.domain.ManualTicketProvideStrategy
import lotto.domain.Rank
import lotto.domain.WinningNumber
import lotto.provider.ticket.MockTicketProvider
import lotto.generator.ticket.ExactTicketGenerator
import lotto.generator.ticket.MockLottoShop
import lotto.view.MockInputView
import lotto.view.ResultView

Expand All @@ -25,8 +25,8 @@ class LottoAutoTest : StringSpec({
),
resultView = ResultView(),
).simulate(
lottoTicketsProvider = MockTicketProvider(
ManualTicketProvideStrategy(
lottoShop = MockLottoShop(
ExactTicketGenerator(
LottoTickets(
listOf(
LottoTicket(listOf(1, 2, 3, 4, 5, 6).map { LottoNumber(it) })
Expand All @@ -48,8 +48,8 @@ class LottoAutoTest : StringSpec({
),
resultView = ResultView(),
).simulate(
lottoTicketsProvider = MockTicketProvider(
ManualTicketProvideStrategy(
lottoShop = MockLottoShop(
ExactTicketGenerator(
LottoTickets(
listOf(
LottoTicket(listOf(1, 2, 3, 4, 5, 6).map { LottoNumber(it) })
Expand All @@ -71,8 +71,8 @@ class LottoAutoTest : StringSpec({
),
resultView = ResultView(),
).simulate(
lottoTicketsProvider = MockTicketProvider(
ManualTicketProvideStrategy(
lottoShop = MockLottoShop(
ExactTicketGenerator(
LottoTickets(
listOf(
LottoTicket(listOf(1, 2, 3, 4, 5, 19).map { LottoNumber(it) })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package lotto.generator.ticket

import lotto.domain.LottoTickets

class ExactTicketGenerator(private val lottoTickets: LottoTickets) : TicketGenerator {
override fun create(ticketCount: Int): LottoTickets = lottoTickets

Choose a reason for hiding this comment

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

lottoTickets의 사이즈와 ticketCount 가 일치하지 않는다면 테스트에 문제가 생길수도 있을거같아요

}
8 changes: 8 additions & 0 deletions src/test/kotlin/lotto/generator/ticket/MockLottoShop.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package lotto.generator.ticket

import lotto.domain.LottoTickets

class MockLottoShop(private val ticketGenerateStrategy: ExactTicketGenerator) : LottoShop {
override fun provideAutoTickets(ticketCount: Int): LottoTickets = ticketGenerateStrategy.create(ticketCount)
override fun provideManualTickets(ticketCount: Int): LottoTickets = LottoTickets(listOf())
}
8 changes: 0 additions & 8 deletions src/test/kotlin/lotto/provider/ticket/MockTicketProvider.kt

This file was deleted.

6 changes: 5 additions & 1 deletion src/test/kotlin/lotto/view/MockInputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ class MockInputView(

override fun getWinningNumber(): WinningNumber = winningNumber

override fun printPurchasedLotto(lottoTickets: LottoTickets) = Unit
override fun printPurchasedLotto(autoLottoTickets: LottoTickets, manualLottoTickets: LottoTickets) = Unit

override fun getManualLottoCount(): Int = 0

override fun printManualLottoInputString() = Unit
}