From 5bb9b489e74e0f8bf7b72239400e62363172f771 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Sat, 17 Feb 2024 16:38:46 +0900
Subject: [PATCH 1/9] =?UTF-8?q?feat:=20DI=20=EC=BB=A8=ED=85=8C=EC=9D=B4?=
=?UTF-8?q?=EB=84=88=20-=201=EB=8B=A8=EA=B3=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/.name | 1 +
.idea/compiler.xml | 6 ++++
kotlin-lotto/build.gradle.kts | 2 ++
.../src/main/kotlin/lotto/Application.kt | 2 +-
.../lotto/global/DependencyInjection.kt | 31 +++++++++++++++++++
5 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 .idea/.name
create mode 100644 .idea/compiler.xml
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..35fe63d
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+kotlin-baseball
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kotlin-lotto/build.gradle.kts b/kotlin-lotto/build.gradle.kts
index c006c73..05763c2 100644
--- a/kotlin-lotto/build.gradle.kts
+++ b/kotlin-lotto/build.gradle.kts
@@ -9,6 +9,8 @@ repositories {
dependencies {
implementation("com.github.woowacourse-projects:mission-utils:1.1.0")
+ implementation("org.jetbrains.kotlin-reflection:1.9.0")
+ implementation(kotlin("reflect"))
}
java {
diff --git a/kotlin-lotto/src/main/kotlin/lotto/Application.kt b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
index d716876..b0a817a 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/Application.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
@@ -1,5 +1,5 @@
package lotto
fun main() {
- TODO("프로그램 구현")
+
}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
new file mode 100644
index 0000000..5dddf06
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
@@ -0,0 +1,31 @@
+package lotto.global
+
+import kotlin.reflect.KClass
+
+object ContainerV1 {
+ // 등록한 클래스를 보관! = KClass를 보관
+
+ private val registeredClasses = mutableSetOf>()
+
+ fun register(clazz: KClass<*>) {
+ registeredClasses.add(clazz)
+ }
+
+ fun getInstance(type: KClass) : T =
+ registeredClasses.firstOrNull { clazz -> clazz == type}
+ ?.let { clazz -> clazz.constructors.first().call() as T }
+ ?: throw IllegalArgumentException("해당 인스턴스 타입을 찾을 수 없습니다.")
+
+}
+
+fun main() {
+ ContainerV1.register(AService::class)
+ val aService = ContainerV1.getInstance(AService::class)
+ aService.print()
+}
+
+class AService {
+ fun print() {
+ println("A Service 입니다")
+ }
+}
\ No newline at end of file
From f7282b29ed62f928424f940c8ec9fa60c9e66af1 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Sat, 17 Feb 2024 17:22:03 +0900
Subject: [PATCH 2/9] =?UTF-8?q?feat:=20DI=20=EC=BB=A8=ED=85=8C=EC=9D=B4?=
=?UTF-8?q?=EB=84=88=20-=202=EB=8B=A8=EA=B3=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
kotlin-lotto/build.gradle.kts | 1 +
.../lotto/global/DependencyInjection.kt | 75 ++++++++++++++++++-
2 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/kotlin-lotto/build.gradle.kts b/kotlin-lotto/build.gradle.kts
index 05763c2..67f05b1 100644
--- a/kotlin-lotto/build.gradle.kts
+++ b/kotlin-lotto/build.gradle.kts
@@ -9,6 +9,7 @@ repositories {
dependencies {
implementation("com.github.woowacourse-projects:mission-utils:1.1.0")
+ implementation("org.reflections:reflections:0.10.2")
implementation("org.jetbrains.kotlin-reflection:1.9.0")
implementation(kotlin("reflect"))
}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
index 5dddf06..1ce2bd5 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
@@ -1,6 +1,9 @@
package lotto.global
import kotlin.reflect.KClass
+import kotlin.reflect.KFunction
+import kotlin.reflect.KParameter
+import kotlin.reflect.cast
object ContainerV1 {
// 등록한 클래스를 보관! = KClass를 보관
@@ -18,14 +21,78 @@ object ContainerV1 {
}
+object ContainerV2 {
+ // 등록한 클래스를 보관! = KClass를 보관
+
+ private val registeredClasses = mutableSetOf>()
+ private val cachedInstances = mutableMapOf, Any>()
+
+ fun register(clazz: KClass<*>) {
+ registeredClasses.add(clazz)
+ }
+
+ fun getInstance(type: KClass) : T {
+ if (type in cachedInstances) {
+ return type.cast(cachedInstances[type])
+ }
+
+ val instance = registeredClasses.firstOrNull { clazz -> clazz == type }
+ ?.let { clazz -> instantiate(clazz) as T }
+ ?: throw IllegalArgumentException("해당 인스턴스 타입을 찾을 수 없습니다.")
+
+ cachedInstances[type] = instance
+ return instance
+ }
+
+ private fun instantiate(clazz: KClass): T {
+ val constructor = findUsableConstructor(clazz)
+ val params = constructor.parameters
+ .map { param -> getInstance(param.type.classifier as KClass<*>) }
+ .toTypedArray()
+
+ return constructor.call(*params)
+ }
+
+ // clazz의 constructor 들 중, 사용할 수 있는 constructor
+ // constructor 에 넣어야 하는 타입들이 모두 등록된 경우(컨테이너에서 관리하고 있는 경우를 의미)
+
+ private fun findUsableConstructor(clazz: KClass): KFunction =
+ clazz.constructors.firstOrNull { constructor -> constructor.parameters.isAllRegistered }
+ ?: throw IllegalArgumentException("사용할 수 있는 생성자가 없습니다")
+
+ private val List.isAllRegistered: Boolean
+ get() = this.all { it.type.classifier in registeredClasses }
+
+}
+
fun main() {
- ContainerV1.register(AService::class)
- val aService = ContainerV1.getInstance(AService::class)
- aService.print()
+// ContainerV1.register(AService::class)
+// val aService = ContainerV1.getInstance(AService::class)
+// aService.print()
+
+ ContainerV2.register(AService::class)
+ ContainerV2.register(BService::class)
+
+ val bService = ContainerV2.getInstance(BService::class)
+ bService.print()
}
class AService {
fun print() {
println("A Service 입니다")
}
-}
\ No newline at end of file
+}
+
+class BService (
+ private val aService: AService,
+ private val cService: CService?,
+) {
+
+ constructor(aService: AService): this(aService, null)
+
+ fun print() {
+ this.aService.print()
+ }
+}
+
+class CService
\ No newline at end of file
From 60a847fb839ea3b9a4ca522915c624eab982f04c Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Sun, 18 Feb 2024 15:50:52 +0900
Subject: [PATCH 3/9] =?UTF-8?q?feat:=20DI=20=EC=BB=A8=ED=85=8C=EC=9D=B4?=
=?UTF-8?q?=EB=84=88=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/kotlin/lotto/Application.kt | 8 +++++++
kotlin-lotto/src/main/kotlin/lotto/Lotto.kt | 7 ++++++
.../src/main/kotlin/lotto/global/Component.kt | 4 ++++
.../lotto/global/DependencyInjection.kt | 24 +++++++++++--------
4 files changed, 33 insertions(+), 10 deletions(-)
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/global/Component.kt
diff --git a/kotlin-lotto/src/main/kotlin/lotto/Application.kt b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
index b0a817a..f5a1e4f 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/Application.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
@@ -1,5 +1,13 @@
package lotto
+import lotto.global.BService
+import lotto.global.ContainerV2
+import lotto.global.start
+
fun main() {
+ start(Lotto::class)
+ val instance = ContainerV2.getInstance(Lotto::class)
+ instance.printHello()
+
}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt b/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
index 5ca00b4..5dece20 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
@@ -1,9 +1,16 @@
package lotto
+import lotto.global.Component
+
+@Component
class Lotto(private val numbers: List) {
init {
require(numbers.size == 6)
}
// TODO: 추가 기능 구현
+
+ fun printHello() {
+ println("HI")
+ }
}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/global/Component.kt b/kotlin-lotto/src/main/kotlin/lotto/global/Component.kt
new file mode 100644
index 0000000..9e5169b
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/global/Component.kt
@@ -0,0 +1,4 @@
+package lotto.global
+
+annotation class Component
+
diff --git a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
index 1ce2bd5..275fdd0 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
@@ -1,5 +1,6 @@
package lotto.global
+import org.reflections.Reflections
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
@@ -65,24 +66,27 @@ object ContainerV2 {
}
-fun main() {
-// ContainerV1.register(AService::class)
-// val aService = ContainerV1.getInstance(AService::class)
-// aService.print()
-
- ContainerV2.register(AService::class)
- ContainerV2.register(BService::class)
-
- val bService = ContainerV2.getInstance(BService::class)
- bService.print()
+fun start(clazz: KClass<*>) {
+ val reflections = Reflections(clazz.packageName)
+ val jClasses = reflections.getTypesAnnotatedWith(Component::class.java)
+ jClasses.forEach { jClasses -> ContainerV2.register(jClasses.kotlin) }
}
+private val KClass<*>.packageName: String
+ get() {
+ val qualifiedName = this.qualifiedName ?: throw IllegalArgumentException("익명 객체입니다!")
+ val hierarchy = qualifiedName.split(".")
+ return hierarchy.subList(0, hierarchy.lastIndex).joinToString(".")
+ }
+
+@Component
class AService {
fun print() {
println("A Service 입니다")
}
}
+@Component
class BService (
private val aService: AService,
private val cService: CService?,
From 362327eb569ff87c08cd1e2bcc98ee375def0009 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Wed, 21 Feb 2024 01:46:56 +0900
Subject: [PATCH 4/9] =?UTF-8?q?feat:=201=EC=B0=A8=20=EA=B5=AC=ED=98=84=20?=
=?UTF-8?q?=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/kotlin/lotto/Application.kt | 16 +++---
kotlin-lotto/src/main/kotlin/lotto/Lotto.kt | 16 ------
.../lotto/controller/LottoController.kt | 52 +++++++++++++++++++
.../lotto/global/DependencyInjection.kt | 46 ++--------------
.../src/main/kotlin/lotto/model/Lotto.kt | 26 ++++++++++
.../src/main/kotlin/lotto/model/LottoBuyer.kt | 16 ++++++
.../kotlin/lotto/model/LottoGameManager.kt | 36 +++++++++++++
.../kotlin/lotto/model/LottoWinningRank.kt | 21 ++++++++
.../kotlin/lotto/view/LottoGameMessageView.kt | 37 +++++++++++++
.../src/test/kotlin/lotto/LottoTest.kt | 1 +
10 files changed, 202 insertions(+), 65 deletions(-)
delete mode 100644 kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/model/LottoBuyer.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/model/LottoWinningRank.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/view/LottoGameMessageView.kt
diff --git a/kotlin-lotto/src/main/kotlin/lotto/Application.kt b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
index f5a1e4f..4bd3b79 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/Application.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/Application.kt
@@ -1,13 +1,17 @@
package lotto
-import lotto.global.BService
-import lotto.global.ContainerV2
-import lotto.global.start
+import lotto.controller.LottoController
+import lotto.global.DIContainer
+import lotto.global.componentScan
+import lotto.model.LottoGameManager
+import lotto.view.LottoGameMessageView
+
+class Application
fun main() {
+ componentScan(Application::class)
- start(Lotto::class)
- val instance = ContainerV2.getInstance(Lotto::class)
- instance.printHello()
+ val lottoGameManager = DIContainer.getInstance(LottoGameManager::class)
+ lottoGameManager.run()
}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt b/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
deleted file mode 100644
index 5dece20..0000000
--- a/kotlin-lotto/src/main/kotlin/lotto/Lotto.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package lotto
-
-import lotto.global.Component
-
-@Component
-class Lotto(private val numbers: List) {
- init {
- require(numbers.size == 6)
- }
-
- // TODO: 추가 기능 구현
-
- fun printHello() {
- println("HI")
- }
-}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
new file mode 100644
index 0000000..401e927
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
@@ -0,0 +1,52 @@
+package lotto.controller
+
+import camp.nextstep.edu.missionutils.Console
+import camp.nextstep.edu.missionutils.Randoms
+import lotto.global.Component
+import lotto.model.Lotto
+import lotto.model.LottoBuyer
+import lotto.model.LottoWinningRank
+import lotto.view.LottoGameMessageView
+
+@Component
+class LottoController(
+ private val lottoGameMessageView: LottoGameMessageView
+) {
+
+ fun purchaseLotto(): Int {
+ lottoGameMessageView.announcePurchaseMessage()
+ return (Console.readLine()
+ ?.toIntOrNull()
+ ?: IllegalArgumentException("올바른 구입금액을 입력해 주세요.")) as Int
+ }
+
+ fun enterWinningNumbers(): List {
+ lottoGameMessageView.announceEnterWinningNumbers()
+ return (Console.readLine()
+ ?.split(",")
+ ?.map { it.toInt() }
+ ?: throw IllegalArgumentException("올바른 당첨 번호를 입력해 주세요."))
+ }
+
+ fun enterBonusNumber(): Int {
+ lottoGameMessageView.announceEnterBonusNumbers()
+ return Console.readLine()
+ ?.toIntOrNull()
+ ?: throw IllegalArgumentException("올바른 보너스 번호를 입력해 주세요.")
+ }
+
+ fun announceResult(lottoResult: List, purchaseAmount: Int) {
+ lottoGameMessageView.announceLottoResult(lottoResult, purchaseAmount)
+ }
+
+ fun announceLottoNumbers(purchaseAmount: Int): List {
+ val randomLottos = List(purchaseAmount / 1000) { Lotto(generateRandomLottoNumbers()) }
+ lottoGameMessageView.announcePurchasedLottos(randomLottos)
+ return randomLottos
+ }
+
+ private fun generateRandomLottoNumbers(): List =
+ Randoms.pickUniqueNumbersInRange(Lotto.LOTTO_START_NUMBER, Lotto.LOTTO_END_NUMBER, Lotto.LOTTO_TOTAL_COUNT)
+
+
+}
\ No newline at end of file
diff --git a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
index 275fdd0..52d0dec 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/global/DependencyInjection.kt
@@ -6,25 +6,8 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.cast
-object ContainerV1 {
- // 등록한 클래스를 보관! = KClass를 보관
-
- private val registeredClasses = mutableSetOf>()
-
- fun register(clazz: KClass<*>) {
- registeredClasses.add(clazz)
- }
-
- fun getInstance(type: KClass) : T =
- registeredClasses.firstOrNull { clazz -> clazz == type}
- ?.let { clazz -> clazz.constructors.first().call() as T }
- ?: throw IllegalArgumentException("해당 인스턴스 타입을 찾을 수 없습니다.")
-
-}
-
-object ContainerV2 {
- // 등록한 클래스를 보관! = KClass를 보관
+object DIContainer {
private val registeredClasses = mutableSetOf>()
private val cachedInstances = mutableMapOf, Any>()
@@ -56,7 +39,6 @@ object ContainerV2 {
// clazz의 constructor 들 중, 사용할 수 있는 constructor
// constructor 에 넣어야 하는 타입들이 모두 등록된 경우(컨테이너에서 관리하고 있는 경우를 의미)
-
private fun findUsableConstructor(clazz: KClass): KFunction =
clazz.constructors.firstOrNull { constructor -> constructor.parameters.isAllRegistered }
?: throw IllegalArgumentException("사용할 수 있는 생성자가 없습니다")
@@ -66,10 +48,10 @@ object ContainerV2 {
}
-fun start(clazz: KClass<*>) {
+fun componentScan(clazz: KClass<*>) {
val reflections = Reflections(clazz.packageName)
val jClasses = reflections.getTypesAnnotatedWith(Component::class.java)
- jClasses.forEach { jClasses -> ContainerV2.register(jClasses.kotlin) }
+ jClasses.forEach { jClasses -> DIContainer.register(jClasses.kotlin) }
}
private val KClass<*>.packageName: String
@@ -78,25 +60,3 @@ private val KClass<*>.packageName: String
val hierarchy = qualifiedName.split(".")
return hierarchy.subList(0, hierarchy.lastIndex).joinToString(".")
}
-
-@Component
-class AService {
- fun print() {
- println("A Service 입니다")
- }
-}
-
-@Component
-class BService (
- private val aService: AService,
- private val cService: CService?,
-) {
-
- constructor(aService: AService): this(aService, null)
-
- fun print() {
- this.aService.print()
- }
-}
-
-class CService
\ No newline at end of file
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt b/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
new file mode 100644
index 0000000..13cd19e
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
@@ -0,0 +1,26 @@
+package lotto.model
+
+import lotto.global.Component
+
+class Lotto(private val numbers: List) {
+ init {
+ require(numbers.size == 6)
+ }
+
+ companion object {
+ const val LOTTO_START_NUMBER = 1
+ const val LOTTO_END_NUMBER = 45
+ const val LOTTO_TOTAL_COUNT = 6
+ }
+
+ fun count(winningNumbers: List): Int =
+ (numbers intersect winningNumbers.toSet()).size
+
+
+ fun count(bonusNumber: Int): Int =
+ if (numbers.contains(bonusNumber)) 1 else 0
+
+ override fun toString(): String =
+ numbers.toString()
+
+}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/LottoBuyer.kt b/kotlin-lotto/src/main/kotlin/lotto/model/LottoBuyer.kt
new file mode 100644
index 0000000..6a37c81
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/LottoBuyer.kt
@@ -0,0 +1,16 @@
+package lotto.model
+
+class LottoBuyer(
+ private val purchasedLottos : List,
+ private val winningNumbers: List,
+ private val bonusNumber: Int
+) {
+
+ fun compareLottoNumbers(): List =
+ purchasedLottos.map { lotto ->
+ LottoWinningRank.entries.firstOrNull { rank ->
+ rank.isRankMatch(lotto.count(winningNumbers), lotto.count(bonusNumber))
+ }
+ }
+
+}
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
new file mode 100644
index 0000000..612148e
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
@@ -0,0 +1,36 @@
+package lotto.model
+
+import camp.nextstep.edu.missionutils.Randoms
+import lotto.controller.LottoController
+import lotto.global.Component
+
+@Component
+class LottoGameManager(
+ private val lottoController: LottoController
+) {
+
+ fun run() {
+ // STEP1 > 구입금액 입력 받기
+ val purchaseAmount = lottoController.purchaseLotto()
+
+ val randomLottos = lottoController.announceLottoNumbers(purchaseAmount)
+
+ // STEP2 > 당첨 번호 입력 받기
+ val winningNumbers = lottoController.enterWinningNumbers()
+
+ // STEP3 > 보너스 번호 입력 받기
+ val bonusNumber = lottoController.enterBonusNumber()
+
+ // STEP4 > 로또 당첨 내역 출력
+ val lottoBuyer = LottoBuyer(
+ randomLottos,
+ winningNumbers,
+ bonusNumber
+ )
+
+ val lottoResultList = lottoBuyer.compareLottoNumbers()
+ lottoController.announceResult(lottoResultList, purchaseAmount)
+ }
+
+
+}
\ No newline at end of file
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/LottoWinningRank.kt b/kotlin-lotto/src/main/kotlin/lotto/model/LottoWinningRank.kt
new file mode 100644
index 0000000..5bf9e2e
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/LottoWinningRank.kt
@@ -0,0 +1,21 @@
+package lotto.model
+
+import java.util.function.BiFunction
+
+enum class LottoWinningRank(
+ val matchCount: Int,
+ val bonusCount: Int,
+ val lottoPrice: Long,
+ val isWinningRank: (matchCount: Int, bonusCount: Int) -> Boolean
+) {
+
+ FIRST_PLACE(6, 0, 2_000_000_000, { matchCount, bonusCount -> matchCount == 6 }),
+ SECOND_PLACE(5, 1, 30_000_000, { matchCount, bonusCount -> matchCount == 5 && bonusCount == 1 }),
+ THIRD_PLACE(5, 0, 1_500_000, { matchCount, bonusCount -> matchCount == 5 && bonusCount == 0 }),
+ FOURTH_PLACE(4, 0, 50_000, { matchCount, bonusCount -> matchCount == 4}),
+ FIFTH_PLACE(3, 0, 5_000, { matchCount, bonusCount -> matchCount == 3 }),
+ ;
+
+ fun isRankMatch(matchCount: Int, bonusCount: Int) =
+ isWinningRank(matchCount, bonusCount)
+}
\ No newline at end of file
diff --git a/kotlin-lotto/src/main/kotlin/lotto/view/LottoGameMessageView.kt b/kotlin-lotto/src/main/kotlin/lotto/view/LottoGameMessageView.kt
new file mode 100644
index 0000000..4875370
--- /dev/null
+++ b/kotlin-lotto/src/main/kotlin/lotto/view/LottoGameMessageView.kt
@@ -0,0 +1,37 @@
+package lotto.view
+
+import lotto.model.Lotto
+import lotto.global.Component
+import lotto.model.LottoWinningRank
+
+@Component
+class LottoGameMessageView {
+
+ fun announcePurchaseMessage() = println("구입금액을 입력해 주세요.")
+
+ fun announcePurchasedLottos(purchasedLottos: List) {
+ println("\n${purchasedLottos.size}개를 구매했습니다.")
+ purchasedLottos.forEach{ println(it) }
+ }
+
+ fun announceEnterWinningNumbers() = println("\n당첨 번호를 입력해 주세요.")
+
+ fun announceEnterBonusNumbers() = println("\n보너스 번호를 입력해 주세요.")
+
+ fun announceLottoResult(lottoResultDto: List, purchaseAmount: Int) =
+ println("""
+
+ 당첨 통계
+ ---
+ 3개 일치 (5,000원) - ${lottoResultDto.count { it == LottoWinningRank.FIFTH_PLACE}}개
+ 4개 일치 (50,000원) - ${lottoResultDto.count { it == LottoWinningRank.FOURTH_PLACE }}개
+ 5개 일치 (1,500,000원) - ${lottoResultDto.count { it == LottoWinningRank.THIRD_PLACE }}개
+ 5개 일치, 보너스 볼 일치 (30,000,000원) - ${lottoResultDto.count { it == LottoWinningRank.SECOND_PLACE }}개
+ 6개 일치 (2,000,000,000원) - ${lottoResultDto.count { it == LottoWinningRank.FIRST_PLACE }}개
+ 총 수익률은 ${"%.1f".format(calculateTotalRateOfReturn(lottoResultDto, purchaseAmount))}%입니다.
+ """.trimIndent())
+
+ private fun calculateTotalRateOfReturn(lottoResultDto: List, purchaseAmount: Int): Double =
+ lottoResultDto.sumOf { it?.lottoPrice ?: 0L }.toDouble() / purchaseAmount * 100
+
+}
\ No newline at end of file
diff --git a/kotlin-lotto/src/test/kotlin/lotto/LottoTest.kt b/kotlin-lotto/src/test/kotlin/lotto/LottoTest.kt
index 11d85ac..666e080 100644
--- a/kotlin-lotto/src/test/kotlin/lotto/LottoTest.kt
+++ b/kotlin-lotto/src/test/kotlin/lotto/LottoTest.kt
@@ -1,5 +1,6 @@
package lotto
+import lotto.model.Lotto
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
From 94564218579df55b07d58870f1c1f2dc3fa26f31 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Wed, 21 Feb 2024 02:25:21 +0900
Subject: [PATCH 5/9] =?UTF-8?q?feat:=202=EC=B0=A8=20=EA=B5=AC=ED=98=84?=
=?UTF-8?q?=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../lotto/controller/LottoController.kt | 24 +++++++++++++------
.../src/main/kotlin/lotto/model/Lotto.kt | 1 +
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
index 401e927..a80ebc5 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
@@ -15,24 +15,35 @@ class LottoController(
fun purchaseLotto(): Int {
lottoGameMessageView.announcePurchaseMessage()
- return (Console.readLine()
- ?.toIntOrNull()
- ?: IllegalArgumentException("올바른 구입금액을 입력해 주세요.")) as Int
+ while (true) {
+ try {
+ return (Console.readLine()
+ ?.toIntOrNull()
+ ?: IllegalArgumentException("[ERROR] 올바른 구입금액을 입력해 주세요.")) as Int
+ } catch (e: IllegalArgumentException) {
+ println(e.message)
+ } catch (e: ClassCastException) {
+ println("[ERROR] 올바른 구매금액을 입력해주세요.")
+ }
+ }
}
fun enterWinningNumbers(): List {
lottoGameMessageView.announceEnterWinningNumbers()
- return (Console.readLine()
+ val winningNumbers = (Console.readLine()
?.split(",")
?.map { it.toInt() }
- ?: throw IllegalArgumentException("올바른 당첨 번호를 입력해 주세요."))
+ ?: throw IllegalArgumentException("[ERROR] 올바른 당첨 번호를 입력해 주세요."))
+
+ return winningNumbers
+
}
fun enterBonusNumber(): Int {
lottoGameMessageView.announceEnterBonusNumbers()
return Console.readLine()
?.toIntOrNull()
- ?: throw IllegalArgumentException("올바른 보너스 번호를 입력해 주세요.")
+ ?: throw IllegalArgumentException("[ERROR] 올바른 보너스 번호를 입력해 주세요.")
}
fun announceResult(lottoResult: List, purchaseAmount: Int) {
@@ -48,5 +59,4 @@ class LottoController(
private fun generateRandomLottoNumbers(): List =
Randoms.pickUniqueNumbersInRange(Lotto.LOTTO_START_NUMBER, Lotto.LOTTO_END_NUMBER, Lotto.LOTTO_TOTAL_COUNT)
-
}
\ No newline at end of file
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt b/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
index 13cd19e..a4c8a3c 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/Lotto.kt
@@ -5,6 +5,7 @@ import lotto.global.Component
class Lotto(private val numbers: List) {
init {
require(numbers.size == 6)
+ require(numbers.distinct().size == numbers.size)
}
companion object {
From a1f71515ab9a2db3344f051e0a7d32af3af4c15f Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Wed, 21 Feb 2024 02:27:40 +0900
Subject: [PATCH 6/9] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/kotlin/lotto/model/LottoGameManager.kt | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
index 612148e..61f19d2 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
@@ -13,15 +13,16 @@ class LottoGameManager(
// STEP1 > 구입금액 입력 받기
val purchaseAmount = lottoController.purchaseLotto()
+ // STEP2 > 구매 내역 출력
val randomLottos = lottoController.announceLottoNumbers(purchaseAmount)
- // STEP2 > 당첨 번호 입력 받기
+ // STEP3 > 당첨 번호 입력 받기
val winningNumbers = lottoController.enterWinningNumbers()
- // STEP3 > 보너스 번호 입력 받기
+ // STEP4 > 보너스 번호 입력 받기
val bonusNumber = lottoController.enterBonusNumber()
- // STEP4 > 로또 당첨 내역 출력
+ // STEP5 > 로또 당첨 내역 출력
val lottoBuyer = LottoBuyer(
randomLottos,
winningNumbers,
From a1b9c52757a00176aefcca6c1c2a17e549250a21 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Wed, 21 Feb 2024 02:41:36 +0900
Subject: [PATCH 7/9] =?UTF-8?q?chore:=20=EA=B0=9C=ED=96=89=20=EC=A0=95?=
=?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EC=9D=B8=EB=9D=BC=EC=9D=B8=EC=9C=BC?=
=?UTF-8?q?=EB=A1=9C=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/kotlin/lotto/controller/LottoController.kt | 4 +---
kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt | 1 -
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
index a80ebc5..f4435aa 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/controller/LottoController.kt
@@ -30,13 +30,11 @@ class LottoController(
fun enterWinningNumbers(): List {
lottoGameMessageView.announceEnterWinningNumbers()
- val winningNumbers = (Console.readLine()
+ return (Console.readLine()
?.split(",")
?.map { it.toInt() }
?: throw IllegalArgumentException("[ERROR] 올바른 당첨 번호를 입력해 주세요."))
- return winningNumbers
-
}
fun enterBonusNumber(): Int {
diff --git a/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
index 61f19d2..911643d 100644
--- a/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
+++ b/kotlin-lotto/src/main/kotlin/lotto/model/LottoGameManager.kt
@@ -33,5 +33,4 @@ class LottoGameManager(
lottoController.announceResult(lottoResultList, purchaseAmount)
}
-
}
\ No newline at end of file
From 09f6d4541705b4c89f0272270fc2a93cd4d2e673 Mon Sep 17 00:00:00 2001
From: leesoobeen <02ggang9@gmail.com>
Date: Mon, 4 Mar 2024 16:03:45 +0900
Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EC=82=B0=ED=83=80=20=EB=AF=B8?=
=?UTF-8?q?=EC=85=98=201=EC=B0=A8=20=EA=B5=AC=ED=98=84=20=EC=99=84?=
=?UTF-8?q?=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
kotlin-christmas/build.gradle.kts | 3 +
.../src/main/kotlin/christmas/Application.kt | 8 ++-
.../kotlin/christmas/ChristmasGameManager.kt | 29 +++++++++
.../ChristmasDdayDiscountPolicy.kt | 17 +++++
.../discount_policy/EventDiscountPolicy.kt | 13 ++++
.../EventDiscountPolicyFactory.kt | 6 ++
.../discount_policy/SpecialDiscountPolicy.kt | 20 ++++++
.../discount_policy/WeekdayDiscountPolicy.kt | 23 +++++++
.../discount_policy/WeekendDiscountPolicy.kt | 24 +++++++
.../src/main/kotlin/christmas/domain/Badge.kt | 13 ++++
.../src/main/kotlin/christmas/domain/Menu.kt | 25 ++++++++
.../main/kotlin/christmas/domain/MenuType.kt | 9 +++
.../main/kotlin/christmas/dto/OrderMenuDto.kt | 41 ++++++++++++
.../main/kotlin/christmas/global/Component.kt | 3 +
.../main/kotlin/christmas/global/Container.kt | 62 +++++++++++++++++++
.../main/kotlin/christmas/view/InputView.kt | 58 +++++++++++++++++
.../main/kotlin/christmas/view/OutputView.kt | 58 +++++++++++++++++
.../main/kotlin/lotto/dsl/dockerCompose.kt | 2 +
18 files changed, 413 insertions(+), 1 deletion(-)
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/ChristmasGameManager.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/ChristmasDdayDiscountPolicy.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicy.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicyFactory.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/SpecialDiscountPolicy.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekdayDiscountPolicy.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekendDiscountPolicy.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/domain/Badge.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/domain/Menu.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/domain/MenuType.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/dto/OrderMenuDto.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/global/Component.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/global/Container.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/view/InputView.kt
create mode 100644 kotlin-christmas/src/main/kotlin/christmas/view/OutputView.kt
create mode 100644 kotlin-lotto/src/main/kotlin/lotto/dsl/dockerCompose.kt
diff --git a/kotlin-christmas/build.gradle.kts b/kotlin-christmas/build.gradle.kts
index c006c73..67f05b1 100644
--- a/kotlin-christmas/build.gradle.kts
+++ b/kotlin-christmas/build.gradle.kts
@@ -9,6 +9,9 @@ repositories {
dependencies {
implementation("com.github.woowacourse-projects:mission-utils:1.1.0")
+ implementation("org.reflections:reflections:0.10.2")
+ implementation("org.jetbrains.kotlin-reflection:1.9.0")
+ implementation(kotlin("reflect"))
}
java {
diff --git a/kotlin-christmas/src/main/kotlin/christmas/Application.kt b/kotlin-christmas/src/main/kotlin/christmas/Application.kt
index 8d101ce..cc5b230 100644
--- a/kotlin-christmas/src/main/kotlin/christmas/Application.kt
+++ b/kotlin-christmas/src/main/kotlin/christmas/Application.kt
@@ -1,5 +1,11 @@
package christmas
+import christmas.global.Container
+
+class Application
+
fun main() {
- TODO("프로그램 구현")
+ Container.componentScan(Application::class)
+ val christmasGameManager = Container.getInstance(ChristmasGameManager::class)
+ christmasGameManager.run()
}
diff --git a/kotlin-christmas/src/main/kotlin/christmas/ChristmasGameManager.kt b/kotlin-christmas/src/main/kotlin/christmas/ChristmasGameManager.kt
new file mode 100644
index 0000000..d17c7cd
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/ChristmasGameManager.kt
@@ -0,0 +1,29 @@
+package christmas
+
+import christmas.global.Component
+import christmas.view.InputView
+import christmas.view.OutputView
+
+@Component
+class ChristmasGameManager(
+ private val inputView: InputView,
+ private val outputView: OutputView,
+) {
+
+ fun run() {
+ // STEP1 > 식당 예상 방문 날짜 입력 받기
+ outputView.printEventMessage()
+ val userVisitDay = inputView.getVisitDay()
+
+ // STEP2 > 주문할 메뉴와 개수 입력 받기
+ outputView.printMenuAndCountMessage()
+ val ordersDto = inputView.getOrderMenuAndCount(userVisitDay)
+
+ // STEP3 > 이벤트 혜택 미리보기 출력
+ outputView.printEventListMessage(userVisitDay)
+
+ // STEP4 > 주문 메뉴 출력
+ outputView.printReceipt(ordersDto)
+ }
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/ChristmasDdayDiscountPolicy.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/ChristmasDdayDiscountPolicy.kt
new file mode 100644
index 0000000..3d743f1
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/ChristmasDdayDiscountPolicy.kt
@@ -0,0 +1,17 @@
+package christmas.discount_policy
+
+import christmas.dto.OrderMenuDto
+import christmas.global.Component
+
+@Component
+class ChristmasDdayDiscountPolicy: EventDiscountPolicy {
+
+ override val discountPolicyName: String
+ get() = "크리스마스 디데이 할인"
+
+ override fun isSatisfiedBy(orderMenuDto: OrderMenuDto): Boolean =
+ orderMenuDto.reservationDate in 1..25
+
+ override fun calculateDiscountAmount(orderMenuDto: OrderMenuDto): Long =
+ 1000L + 100L * (orderMenuDto.reservationDate - 1)
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicy.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicy.kt
new file mode 100644
index 0000000..f277089
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicy.kt
@@ -0,0 +1,13 @@
+package christmas.discount_policy
+
+import christmas.dto.OrderMenuDto
+
+interface EventDiscountPolicy {
+
+ val discountPolicyName: String
+
+ fun isSatisfiedBy(orderMenuDto: OrderMenuDto): Boolean
+
+ fun calculateDiscountAmount(orderMenuDto: OrderMenuDto): Long
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicyFactory.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicyFactory.kt
new file mode 100644
index 0000000..500d011
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/EventDiscountPolicyFactory.kt
@@ -0,0 +1,6 @@
+package christmas.discount_policy
+
+fun createEventDiscountPolicy(): List =
+ listOf(ChristmasDdayDiscountPolicy(), SpecialDiscountPolicy(), WeekdayDiscountPolicy(), WeekendDiscountPolicy())
+
+
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/SpecialDiscountPolicy.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/SpecialDiscountPolicy.kt
new file mode 100644
index 0000000..ba3fe09
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/SpecialDiscountPolicy.kt
@@ -0,0 +1,20 @@
+package christmas.discount_policy
+
+import christmas.dto.OrderMenuDto
+import christmas.global.Component
+
+@Component
+class SpecialDiscountPolicy: EventDiscountPolicy {
+
+ override val discountPolicyName: String
+ get() = "특별 할인"
+
+ override fun isSatisfiedBy(orderMenuDto: OrderMenuDto): Boolean {
+ val days = listOf(3, 10, 17, 24, 25, 31)
+ return orderMenuDto.reservationDate in days
+ }
+
+ override fun calculateDiscountAmount(orderMenuDto: OrderMenuDto): Long = 1000L
+
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekdayDiscountPolicy.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekdayDiscountPolicy.kt
new file mode 100644
index 0000000..8b291ba
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekdayDiscountPolicy.kt
@@ -0,0 +1,23 @@
+package christmas.discount_policy
+
+import christmas.domain.MenuType
+import christmas.dto.OrderMenuDto
+import christmas.global.Component
+
+@Component
+class WeekdayDiscountPolicy: EventDiscountPolicy {
+
+ override val discountPolicyName: String
+ get() = "평일 할인"
+
+ override fun isSatisfiedBy(orderMenuDto: OrderMenuDto): Boolean {
+ val days = listOf(3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 24, 25, 26, 27, 28, 31)
+ return orderMenuDto.reservationDate in days
+ }
+
+ override fun calculateDiscountAmount(orderMenuDto: OrderMenuDto): Long =
+ 2023L * orderMenuDto.orderList.entries
+ .filter { it.key.menuType == MenuType.DESSERT }
+ .sumOf { it.value }
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekendDiscountPolicy.kt b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekendDiscountPolicy.kt
new file mode 100644
index 0000000..5c2b998
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/discount_policy/WeekendDiscountPolicy.kt
@@ -0,0 +1,24 @@
+package christmas.discount_policy
+
+import christmas.domain.MenuType
+import christmas.dto.OrderMenuDto
+import christmas.global.Component
+
+@Component
+class WeekendDiscountPolicy: EventDiscountPolicy {
+
+ override val discountPolicyName: String
+ get() = "주말 할인"
+
+ override fun isSatisfiedBy(orderMenuDto: OrderMenuDto): Boolean {
+ val days = listOf(1, 2, 8, 9, 15, 16, 22, 23, 29, 30)
+ return orderMenuDto.reservationDate in days
+ }
+
+ override fun calculateDiscountAmount(orderMenuDto: OrderMenuDto): Long =
+ 2023L * orderMenuDto.orderList.entries
+ .filter { it.key.menuType == MenuType.MAIN }
+ .sumOf { it.value }
+
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/domain/Badge.kt b/kotlin-christmas/src/main/kotlin/christmas/domain/Badge.kt
new file mode 100644
index 0000000..27b9dc9
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/domain/Badge.kt
@@ -0,0 +1,13 @@
+package christmas.domain
+
+enum class Badge(
+ val badgeName: String,
+ val badgePrice: Long
+) {
+
+ SANTA("산타", 20_000L),
+ TREE("트리", 10_000L),
+ STAR("별", 5_000L),
+ NOTHING("없음", 0L),
+
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/domain/Menu.kt b/kotlin-christmas/src/main/kotlin/christmas/domain/Menu.kt
new file mode 100644
index 0000000..d834893
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/domain/Menu.kt
@@ -0,0 +1,25 @@
+package christmas.domain
+
+enum class Menu(
+ val mainMenuName: String,
+ val mainMenuPrice: Long,
+ val menuType: MenuType
+) {
+ MUSHROOM_SOUP("양송이수프", 6_000, MenuType.APPETIZER),
+ TAPAS("타파스", 5_500, MenuType.APPETIZER),
+ CAESAR_SALAD("시저샐러드", 8_000, MenuType.APPETIZER),
+
+ T_BONE_STEAK("티본스테이크", 55_000, MenuType.MAIN),
+ BARBECUE_RIB("바비큐립", 54_000, MenuType.MAIN),
+ SEAFOOD_PASTA("해산물파스타", 35_000, MenuType.MAIN),
+ CHRISTMAS_PASTA("크리스마스파스타", 25_000, MenuType.MAIN),
+
+ CHOCOLATE_CAKE("초코케이크", 15_000, MenuType.DESSERT),
+ ICECREAM("아이스크림", 5_000, MenuType.DESSERT),
+
+ ZERO_COLA("제로콜라", 3_000, MenuType.DRINK),
+ RED_WINE("레드와인", 60_000, MenuType.DRINK),
+ CHAMPAGNE("샴페인", 25_000, MenuType.DRINK),
+
+ NOTHING("없음", 0L, MenuType.NOTHING),
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/domain/MenuType.kt b/kotlin-christmas/src/main/kotlin/christmas/domain/MenuType.kt
new file mode 100644
index 0000000..cd5c2bb
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/domain/MenuType.kt
@@ -0,0 +1,9 @@
+package christmas.domain
+
+enum class MenuType {
+ APPETIZER,
+ MAIN,
+ DESSERT,
+ DRINK,
+ NOTHING,
+}
\ No newline at end of file
diff --git a/kotlin-christmas/src/main/kotlin/christmas/dto/OrderMenuDto.kt b/kotlin-christmas/src/main/kotlin/christmas/dto/OrderMenuDto.kt
new file mode 100644
index 0000000..eb93b75
--- /dev/null
+++ b/kotlin-christmas/src/main/kotlin/christmas/dto/OrderMenuDto.kt
@@ -0,0 +1,41 @@
+package christmas.dto
+
+import christmas.discount_policy.EventDiscountPolicy
+import christmas.discount_policy.createEventDiscountPolicy
+import christmas.domain.Badge
+import christmas.domain.Menu
+
+
+class OrderMenuDto(
+ val reservationDate: Int,
+ val orderList: Map