iT邦幫忙

2024 iThome 鐵人賽

DAY 21
1

介紹

Kotlin 的策略模式沒有語法糖,所以跟 Java 的差不多

策略模式實作

  1. 建立促銷介面
interface Promotion {
    fun getType(): String
    fun getPrice(originalPrice: BigDecimal, discount: BigDecimal, quantity: Int): BigDecimal
}
  1. 寫單件折扣算式
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
    }
}
  1. 寫第二個商品折扣算式
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
    }
}
  1. 寫沒有折扣算式
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
    }
}
  1. 建立會員類別,在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
    }
}

策略模式測試

  1. 測試案例
    • 第一個會員 Andy 買一件商品,是單件折扣
    • 第二個會員 Jack 買兩件商品,是第二個商品折扣
    • 第三個會員 艾因利奇曼 買一百件商品,沒有折扣
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()
    }
}
  1. 執行測試
姓名:Andy / 付多少錢:80.0 / 折扣名稱:單件折扣
姓名:Jack / 付多少錢:180.0 / 折扣名稱:第二個商品折扣
姓名:Rich / 付多少錢:10000 / 折扣名稱:沒有折扣

上一篇
113/20 - 策略模式(Strategy)- Java
下一篇
113/22 - 責任鏈模式(Chain of Responsibility)- Java
系列文
肯定會斷賽之在 Android 開發使用設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言