Skip to content

Commit 691cb70

Browse files
committed
[4장_양수진] 데이터 중심 설계 리팩토링
1 parent c25fc1a commit 691cb70

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

src/main/kotlin/yangsooplus/ch04/DiscountCondition.kt

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
package yangsooplus.ch04
22

3+
import java.lang.IllegalArgumentException
34
import java.time.DayOfWeek
45
import java.time.LocalTime
56

67
class DiscountCondition(
78
val type: DiscountConditionType,
8-
val sequence: Int,
9-
val dayOfWeek: DayOfWeek,
10-
val startTime: LocalTime,
11-
val endTime: LocalTime
12-
)
9+
private val sequence: Int,
10+
private val dayOfWeek: DayOfWeek,
11+
private val startTime: LocalTime,
12+
private val endTime: LocalTime
13+
) {
14+
fun isDiscountable(dayOfWeek: DayOfWeek, time: LocalTime): Boolean {
15+
if (type != DiscountConditionType.PERIOD) throw IllegalArgumentException()
16+
return this.dayOfWeek == dayOfWeek && startTime <= time && endTime >= time
17+
}
18+
19+
fun isDiscountable(sequence: Int): Boolean {
20+
if (type != DiscountConditionType.SEQUENCE) throw IllegalArgumentException()
21+
return this.sequence == sequence
22+
}
23+
}
1324

1425
enum class DiscountConditionType{
1526
SEQUENCE, PERIOD

src/main/kotlin/yangsooplus/ch04/Movie.kt

+33-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,46 @@ package yangsooplus.ch04
22

33
import yangsooplus.ch02.Money
44
import java.time.Duration
5+
import java.time.LocalDateTime
56

67
class Movie(
78
val title: String,
89
val runningTime: Duration,
9-
val fee: Money,
10+
private val fee: Money,
1011
val discountConditions: List<DiscountCondition>,
1112

1213
val movieType: MovieType,
13-
val discountAmount: Money,
14-
val discountPercent: Double
15-
)
14+
private val discountAmount: Money,
15+
private val discountPercent: Double
16+
) {
17+
fun calculateAmountDiscountedFee(): Money {
18+
return fee.minus(discountAmount)
19+
}
20+
21+
fun calculatePercentDiscountedFee(): Money {
22+
return fee.minus(fee.times(discountPercent))
23+
}
24+
25+
fun calculateNoneDiscountedFee(): Money = fee
26+
27+
fun isDiscountable(whenScreened: LocalDateTime, sequence: Int): Boolean {
28+
discountConditions.forEach { condition ->
29+
when (condition.type) {
30+
DiscountConditionType.PERIOD -> {
31+
if (condition.isDiscountable(whenScreened.dayOfWeek, whenScreened.toLocalTime()))
32+
return true
33+
}
34+
35+
DiscountConditionType.SEQUENCE -> {
36+
if (condition.isDiscountable(sequence))
37+
return true
38+
}
39+
}
40+
}
41+
return false
42+
}
43+
44+
}
1645

1746
enum class MovieType {
1847
AMOUNT_DISCOUNT, PERCENT_DISCOUNT, NONE_DISCOUNT
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,10 @@
11
package yangsooplus.ch04
22

3-
import yangsooplus.ch02.Money
3+
44

55
class ReservationAgency {
66

77
fun reserve(screening: Screening, customer: Customer, audienceCnt: Int): Reservation {
8-
val movie = screening.movie
9-
10-
var discountable = false
11-
movie.discountConditions.forEach { condition ->
12-
discountable = when (condition.type) {
13-
DiscountConditionType.PERIOD -> {
14-
screening.whenScreened.dayOfWeek == condition.dayOfWeek &&
15-
condition.startTime <= screening.whenScreened.toLocalTime() &&
16-
condition.endTime >= screening.whenScreened.toLocalTime()
17-
}
18-
DiscountConditionType.SEQUENCE -> {
19-
condition.sequence == screening.sequence
20-
}
21-
}
22-
23-
if (discountable) return@forEach
24-
}
25-
26-
val fee = if (discountable) {
27-
val discountAmount = when(movie.movieType) {
28-
MovieType.AMOUNT_DISCOUNT -> movie.discountAmount
29-
MovieType.PERCENT_DISCOUNT -> movie.fee.times(movie.discountPercent)
30-
MovieType.NONE_DISCOUNT -> Money.ZERO
31-
}
32-
movie.fee.minus(discountAmount)
33-
} else {
34-
movie.fee
35-
}
36-
37-
return Reservation(customer, screening, fee, audienceCnt)
8+
return Reservation(customer, screening, screening.calculateFee(audienceCnt), audienceCnt)
389
}
3910
}
+13-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
package yangsooplus.ch04
22

3+
import yangsooplus.ch02.Money
34
import java.time.LocalDateTime
45

56
class Screening(
6-
val movie: Movie,
7+
private val movie: Movie,
78
val sequence: Int,
89
val whenScreened: LocalDateTime
9-
)
10+
) {
11+
12+
fun calculateFee(audienceCnt: Int): Money {
13+
return when (movie.movieType) {
14+
MovieType.AMOUNT_DISCOUNT -> movie.calculateAmountDiscountedFee()
15+
MovieType.PERCENT_DISCOUNT -> movie.calculatePercentDiscountedFee()
16+
MovieType.NONE_DISCOUNT -> movie.calculateNoneDiscountedFee()
17+
}.times(audienceCnt)
18+
}
19+
20+
}

0 commit comments

Comments
 (0)