Kotlin 的策略模式沒有語法糖,所以跟 Java 的差不多
interface Promotion {
fun getType(): String
fun getPrice(originalPrice: BigDecimal, discount: BigDecimal, quantity: Int): BigDecimal
}
class ItemPromotion : Promotion {
override fun getType(): String {
return "單件折扣"
}
override fun getPrice(
originalPrice: BigDecimal,
discount: BigDecimal,
quantity: Int
): BigDecimal {
val price = originalPrice.multiply(discount)
return price
}
}
class SecondItemPromotion : Promotion {
override fun getType(): String {
return "第二個商品折扣"
}
override fun getPrice(
originalPrice: BigDecimal,
discount: BigDecimal,
quantity: Int
): BigDecimal {
var price = originalPrice.multiply(discount)
price = price.add(originalPrice)
return price
}
}
class NoPromotion : Promotion {
override fun getType(): String {
return "沒有折扣"
}
override fun getPrice(
originalPrice: BigDecimal,
discount: BigDecimal,
quantity: Int
): BigDecimal {
val price = originalPrice.multiply(BigDecimal.valueOf(quantity.toLong()))
return price
}
}
getPayMoney
方法寫促銷策略class Member(var name: String) {
var promotion: Promotion? = null
fun getPayMoney(originalPrice: BigDecimal?, discount: BigDecimal?, quantity: Int): BigDecimal {
val money: BigDecimal
when (quantity) {
1 -> {
promotion = ItemPromotion()
money = (promotion as ItemPromotion).getPrice(originalPrice!!, discount!!, quantity)
}
2 -> {
promotion = SecondItemPromotion()
money = (promotion as SecondItemPromotion).getPrice(
originalPrice!!,
discount!!,
quantity
)
}
else -> {
promotion = NoPromotion()
money = (promotion as NoPromotion).getPrice(originalPrice!!, discount!!, quantity)
}
}
return money
}
}
class KotlinTest {
@Test
fun show() {
val text = StringBuilder()
text.append("\n")
text.append(getMemberText(Member("Andy"), 1))
text.append("\n")
text.append(getMemberText(Member("Jack"), 2))
text.append("\n")
text.append(getMemberText(Member("Rich"), 100))
text.append("\n")
assertEquals("測試", text.toString())
}
private fun getMemberText(member: Member, quantity: Int): String {
val memberText = java.lang.StringBuilder()
memberText.append("姓名:")
memberText.append(member.name)
memberText.append(" / ")
memberText.append("付多少錢:")
memberText.append(member.getPayMoney(BigDecimal("100"), BigDecimal("0.8"), quantity))
memberText.append(" / ")
memberText.append("折扣名稱:")
member.promotion.let {
memberText.append(it?.getType())
}
return memberText.toString()
}
}
姓名:Andy / 付多少錢:80.0 / 折扣名稱:單件折扣
姓名:Jack / 付多少錢:180.0 / 折扣名稱:第二個商品折扣
姓名:Rich / 付多少錢:10000 / 折扣名稱:沒有折扣