依然是那句話,Kotlin 在狀態模式也沒有語法糖可以用
interface Level {
fun status(member: Member): String
}
data class Member(
var name: String,
var money: BigDecimal,
var level: Level
) {
fun checkout(): String {
val text = StringBuilder()
text.append("結帳完成")
text.append(" / ")
text.append("會員名稱:")
text.append(name)
text.append(" / ")
text.append("累計消費金額:")
text.append(money.toPlainString())
text.append(" / ")
text.append("會員狀態:")
text.append(level.status(this))
return text.toString()
}
fun addMoney(money: BigDecimal) {
this.money = this.money.add(money)
}
}
class Copper : Level {
override fun status(member: Member): String {
val text = StringBuilder()
if (member.money < BigDecimal.valueOf(500)) {
text.append("消費五百以下,還是銅會員")
} else {
member.level = Silver()
member.checkout()
text.append("消費超過五百,成為銀會員")
}
return text.toString()
}
}
class Silver : Level {
override fun status(member: Member): String {
val text = StringBuilder()
if (member.money < BigDecimal.valueOf(1000)) {
text.append("消費一千以下,還是銀會員")
} else {
member.level = Gold()
member.checkout()
text.append("消費超過一千,成為金會員")
}
return text.toString()
}
}
class Gold : Level {
override fun status(member: Member): String {
val text = StringBuilder()
text.append("升級到金會員,無法再升級")
return text.toString()
}
}
class KotlinTest {
@Test
fun show() {
val text = StringBuilder()
text.append("\n")
val member = Member("Andy", BigDecimal.ZERO, Copper())
text.append(member.checkout())
member.addMoney(BigDecimal.valueOf(50))
text.append("\n")
text.append(member.checkout())
member.addMoney(BigDecimal.valueOf(500))
text.append("\n")
text.append(member.checkout())
member.addMoney(BigDecimal.valueOf(1100))
text.append("\n")
text.append(member.checkout())
member.addMoney(BigDecimal.valueOf(2000))
text.append("\n")
text.append(member.checkout())
assertEquals("測試", text.toString())
}
}
結帳完成 / 會員名稱:Andy / 累計消費金額:0 / 會員狀態:消費五百以下,還是銅會員
結帳完成 / 會員名稱:Andy / 累計消費金額:50 / 會員狀態:消費五百以下,還是銅會員
結帳完成 / 會員名稱:Andy / 累計消費金額:550 / 會員狀態:消費超過五百,成為銀會員
結帳完成 / 會員名稱:Andy / 累計消費金額:1650 / 會員狀態:消費超過一千,成為金會員
結帳完成 / 會員名稱:Andy / 累計消費金額:3650 / 會員狀態:升級到金會員,無法再升級