Skip to content

Commit 3af3a90

Browse files
committed
[14장_김명석] 내용 정리
1 parent e352720 commit 3af3a90

14 files changed

+291
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package kms.chapter14
2+
3+
abstract class BasicRatePolicy(
4+
private val feeRules: List<FeeRule>
5+
) : RatePolicy {
6+
7+
override fun calculateFee(phone: Phone): Money {
8+
return phone.getCalls()
9+
.map { call -> calculate(call) }
10+
.reduce { acc, money -> acc + money }
11+
}
12+
13+
private fun calculate(call: Call): Money {
14+
return feeRules
15+
.map { rule -> rule.calculateFee(call) }
16+
.reduce { acc, money -> acc + money }
17+
}
18+
}

src/main/kotlin/kms/chapter14/Call.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package kms.chapter14
2+
3+
import java.time.Duration
4+
import java.time.LocalDateTime
5+
6+
data class Call(
7+
val interval: DateTimeInterval,
8+
) {
9+
val duration: Duration
10+
get() = interval.duration
11+
12+
val from: LocalDateTime
13+
get() = interval.from
14+
15+
val to: LocalDateTime
16+
get() = interval.to
17+
18+
fun splitByDay() : List<DateTimeInterval> = interval.splitByDay()
19+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package kms.chapter14
2+
3+
import java.time.Duration
4+
import java.time.LocalDate
5+
import java.time.LocalDateTime
6+
import java.time.LocalTime
7+
8+
class DateTimeInterval(
9+
val from: LocalDateTime,
10+
val to: LocalDateTime,
11+
) {
12+
companion object {
13+
fun of(from: LocalDateTime, to: LocalDateTime) = DateTimeInterval(from, to)
14+
15+
fun toMidnight(from: LocalDateTime): DateTimeInterval {
16+
return DateTimeInterval(
17+
from,
18+
LocalDateTime.of(from.toLocalDate(), LocalTime.of(23, 59, 59, 999_999_999))
19+
)
20+
}
21+
22+
fun fromMidnight(to: LocalDateTime): DateTimeInterval {
23+
return DateTimeInterval(
24+
LocalDateTime.of(to.toLocalDate(), LocalTime.of(0, 0)),
25+
to
26+
)
27+
}
28+
29+
fun during(date: LocalDate): DateTimeInterval {
30+
return DateTimeInterval(
31+
LocalDateTime.of(date, LocalTime.of(0, 0)),
32+
LocalDateTime.of(date, LocalTime.of(23, 59, 59, 999_999_999))
33+
)
34+
}
35+
}
36+
37+
val duration
38+
get() = Duration.between(from, to)
39+
40+
fun splitByDay(): List<DateTimeInterval> {
41+
if (days > 0) {
42+
return splitByDay(days)
43+
}
44+
return listOf(this)
45+
}
46+
47+
private fun splitByDay(days: Long): List<DateTimeInterval> {
48+
return mutableListOf<DateTimeInterval>().apply {
49+
add(toMidnight(from))
50+
for (loop in 1 until days) {
51+
add(during(from.toLocalDate().plusDays(loop)))
52+
}
53+
add(fromMidnight(to))
54+
}
55+
56+
}
57+
58+
private val days
59+
get() = Duration.between(from.toLocalDate().atStartOfDay(), to.toLocalDate().atStartOfDay()).toDays()
60+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kms.chapter14
2+
3+
import java.time.DayOfWeek
4+
5+
class DayOfWeekFeeCondition(
6+
private val dayOfWeeks: List<DayOfWeek>
7+
) : FeeCondition {
8+
9+
override fun findTimeIntervals(call: Call): List<DateTimeInterval> {
10+
return call.interval.splitByDay()
11+
.filter { dayOfWeeks.contains(it.from.dayOfWeek) }
12+
}
13+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package kms.chapter14
2+
3+
import java.time.Duration
4+
5+
class DurationFeeCondition(
6+
private val from: Duration,
7+
private val to: Duration,
8+
) : FeeCondition {
9+
10+
override fun findTimeIntervals(call: Call): List<DateTimeInterval> {
11+
if (call.interval.duration < from) {
12+
return emptyList()
13+
}
14+
15+
return listOf(
16+
DateTimeInterval.of(
17+
call.interval.from + from,
18+
if (call.interval.duration > to) {
19+
call.interval.from + to
20+
} else {
21+
call.interval.to
22+
}
23+
)
24+
)
25+
}
26+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package kms.chapter14
2+
3+
interface FeeCondition {
4+
5+
fun findTimeIntervals(call: Call): List<DateTimeInterval>
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package kms.chapter14
2+
3+
import java.time.Duration
4+
import kotlin.math.ceil
5+
6+
class FeePerDuration(
7+
private val fee: Money,
8+
private val duration: Duration,
9+
) {
10+
11+
fun calculate(interval: DateTimeInterval): Money {
12+
return fee * (ceil(interval.duration.toNanos().toDouble() / duration.toNanos()))
13+
}
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kms.chapter14
2+
3+
class FeeRule(
4+
private val feeCondition: FeeCondition,
5+
private val feePerDuration: FeePerDuration,
6+
) {
7+
8+
fun calculateFee(call: Call): Money {
9+
return feeCondition.findTimeIntervals(call)
10+
.map { feePerDuration.calculate(it) }
11+
.reduce { acc, money -> acc + money }
12+
}
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package kms.chapter14
2+
3+
class FixedFeeCondition : FeeCondition {
4+
5+
override fun findTimeIntervals(call: Call): List<DateTimeInterval> {
6+
return listOf(call.interval)
7+
}
8+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package kms.chapter14
2+
3+
import java.math.BigDecimal
4+
5+
class Money(
6+
private val amount: BigDecimal,
7+
) : Comparable<Money> {
8+
operator fun plus(amount: Money): Money {
9+
return Money(this.amount.add(amount.amount))
10+
}
11+
12+
operator fun minus(amount: Money): Money {
13+
return Money(this.amount.subtract(amount.amount))
14+
}
15+
16+
operator fun times(percent: Double): Money {
17+
return Money(this.amount.multiply(BigDecimal.valueOf(percent)))
18+
}
19+
20+
operator fun times(percent: Float): Money {
21+
return Money(this.amount.multiply(BigDecimal.valueOf(percent.toDouble())))
22+
}
23+
24+
operator fun times(value: Int): Money {
25+
return Money(this.amount.multiply(BigDecimal.valueOf(value.toLong())))
26+
}
27+
28+
operator fun times(value: Long): Money {
29+
return Money(this.amount.multiply(BigDecimal.valueOf(value)))
30+
}
31+
32+
override fun compareTo(other: Money): Int {
33+
return amount.compareTo(other.amount)
34+
}
35+
36+
companion object {
37+
fun wons(amount: Long) = Money(BigDecimal.valueOf(amount))
38+
39+
val ZERO = wons(0)
40+
}
41+
}

0 commit comments

Comments
 (0)