iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0

介紹

依然是那句話,Kotlin 在狀態模式也沒有語法糖可以用

狀態模式實作

  1. 建立會員等級介面
interface Level {
    fun status(member: Member): String
}
  1. 建立會員類別
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)
    }
}
  1. 建立銅會員,最基礎的會員
    累計消費五百,可以升等銀會員
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()
    }
}
  1. 建立銀會員
    累計消費一千,可以升等金會員
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()
    }
}
  1. 建立金會員
    最高級會員,無法再升級
class Gold : Level {
    override fun status(member: Member): String {
        val text = StringBuilder()
        text.append("升級到金會員,無法再升級")
        return text.toString()
    }
}

狀態模式測試

  1. 測試案例
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())
    }
}
  1. 執行測試
結帳完成 / 會員名稱:Andy / 累計消費金額:0 / 會員狀態:消費五百以下,還是銅會員
結帳完成 / 會員名稱:Andy / 累計消費金額:50 / 會員狀態:消費五百以下,還是銅會員
結帳完成 / 會員名稱:Andy / 累計消費金額:550 / 會員狀態:消費超過五百,成為銀會員
結帳完成 / 會員名稱:Andy / 累計消費金額:1650 / 會員狀態:消費超過一千,成為金會員
結帳完成 / 會員名稱:Andy / 累計消費金額:3650 / 會員狀態:升級到金會員,無法再升級

上一篇
113/26 - 狀態模式(State)- Java
下一篇
113/28 - 中介者模式(Mediator)- Java
系列文
肯定會斷賽之在 Android 開發使用設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言