Kotlin设计模式实现之行为型设计模式

行为型模式

在软件工程中, 行为型设计模式是用来确认对象之间的公共的交流模式的。通过这样做,这些模式提高了实现这种交流的灵活性。

观察者模式

观察模式通常允许一个对象发布他的状态的变化。其他对象可以进行订阅,当其又任何变化时,其他对象都会马上收到通知。

举例:
    interface TextChangedListener {
        fun onTextChanged(newText: String)
    }

    class PrintingTextChangedListener : TextChangedListener {
        override fun onTextChanged(newText: String) = println("Text is changed to: $newText")
    }

    class TextView {

        var listener: TextChangedListener? = null

        var text: String by Delegates.observable("") { prop, old, new ->
            listener?.onTextChanged(new)
        }
    }
使用
    val textView = TextView()
    textView.listener = PrintingTextChangedListener()
    textView.text = "Lorem ipsum"
    textView.text = "dolor sit amet"
输出
Text is changed to: Lorem ipsum
Text is changed to: dolor sit amet

策略模式

策略模式一般用来创建一个可替换的算法簇,在运行时决定需要什么。

举例:
    class Printer(val stringFormatterStrategy: (String) -> String) {
        fun printString(string: String) = println(stringFormatterStrategy.invoke(string))
    }

    val lowerCaseFormatter: (String) -> String = { it.toLowerCase() }

    val upperCaseFormatter = { it: String -> it.toUpperCase() }
使用
    val lowerCasePrinter = Printer(lowerCaseFormatter)
    lowerCasePrinter.printString("LOREM ipsum DOLOR sit amet")

    val upperCasePrinter = Printer(upperCaseFormatter)
    upperCasePrinter.printString("LOREM ipsum DOLOR sit amet")

    val prefixPrinter = Printer({ "Prefix: " + it })
    prefixPrinter.printString("LOREM ipsum DOLOR sit amet")
输出
lorem ipsum dolor sit amet
LOREM IPSUM DOLOR SIT AMET
Prefix: LOREM ipsum DOLOR sit amet

命令模式

命令模式通常用来表现一个请求,在一个命令对象包括产生的调用和所有它需要的参数。这个命令可能立即被执行,也有可能过一会再使用。

举例:
    interface OrderCommand {
        fun execute()
    }

    class OrderAddCommand(val id: Long) : OrderCommand {
        override fun execute() = println("adding order with id: $id")
    }

    class OrderPayCommand(val id: Long) : OrderCommand {
        override fun execute() = println("paying for order with id: $id")
    }

    class CommandProcessor {

        private val queue = ArrayList<OrderCommand>()

        fun addToQueue(orderCommand: OrderCommand): CommandProcessor
                = apply { queue.add(orderCommand) }

        fun processCommands(): CommandProcessor = apply {
            queue.forEach { it.execute() }
            queue.clear()
        }
    }
使用
    CommandProcessor()
        .addToQueue(OrderAddCommand(1L))
        .addToQueue(OrderAddCommand(2L))
        .addToQueue(OrderPayCommand(2L))
        .addToQueue(OrderPayCommand(1L))
        .processCommands()
输出
adding order with id: 1
adding order with id: 2
paying for order with id: 2
paying for order with id: 1

状态模式

状态模式一般用来在对象内部的状态发生改变时,更改这个对象的行为。这个模式允许在运行时显示的更改一个对象的类。

举例:
    sealed class AuthorizationState {

        class Unauthorized : AuthorizationState()

        class Authorized(val userName: String) : AuthorizationState()
    }

    class AuthorizationPresenter {

        private var state: AuthorizationState = Unauthorized()

        fun loginUser(userLogin: String) {
            state = Authorized(userLogin)
        }

        fun logoutUser() {
            state = Unauthorized()
        }

        val isAuthorized: Boolean
            get() {
                when (state) {
                    is Authorized -> return true
                    else -> return false
                }
            }

        val userLogin: String
            get() {
                when (state) {
                    is Authorized -> return (state as Authorized).userName
                    is Unauthorized -> return "Unknown"
                }
            }

        override fun toString(): String {
            return "User '$userLogin' is logged in: $isAuthorized"
        }
    }
使用
    val authorization = AuthorizationPresenter()
    authorization.loginUser("admin")
    println(authorization)
    authorization.logoutUser()
    println(authorization)
输出
User 'admin' is logged in: true
User 'Unknown' is logged in: false

责任链模式

责任链模式通常用来处理多变的请求,每个请求可能交由不同的处理者进行处理。

举例:
    interface MessageChain {
        fun addLines(inputHeader: String): String
    }

    class AuthenticationHeader(val token: String?, var next: MessageChain? = null) : MessageChain {

        override fun addLines(inputHeader: String): String {
            token ?: throw IllegalStateException("Token should be not null")
            return "$inputHeader Authorization: Bearer $token\n".let { next?.addLines(it) ?: it }
        }
    }

    class ContentTypeHeader(val contentType: String, var next: MessageChain? = null) : MessageChain {

        override fun addLines(inputHeader: String): String 
                = "$inputHeader ContentType: $contentType\n".let { next?.addLines(it) ?: it }
    }

    class BodyPayload(val body: String, var next: MessageChain? = null) : MessageChain {

        override fun addLines(inputHeader: String): String
                = "$inputHeader $body\n".let { next?.addLines(it) ?: it }
    }
使用
    val authenticationHeader = AuthenticationHeader("123456")
    val contentTypeHeader = ContentTypeHeader("json")
    val messageBody = BodyPayload("{\"username\"=\"dbacinski\"}")

    val messageChainWithAuthorization = messageChainWithAuthorization(authenticationHeader, contentTypeHeader, messageBody)
    val messageWithAuthentication = messageChainWithAuthorization.addLines("Message with Authentication:\n")
    println(messageWithAuthentication)

    fun messageChainWithAuthorization(authenticationHeader: AuthenticationHeader, contentTypeHeader: ContentTypeHeader, messageBody: BodyPayload): MessageChain {
        authenticationHeader.next = contentTypeHeader
        contentTypeHeader.next = messageBody
        return authenticationHeader
    }
输出
Message with Authentication:
Authorization: Bearer 123456
ContentType: json
{"username"="dbacinski"}

访问者模式

访问者模式通常用来将结构相对复杂的数据类从功能(根据它们所持有的数据来执行)中分离出来。

举例
    interface ReportVisitable {
        fun accept(visitor: ReportVisitor)
    }

    class FixedPriceContract(val costPerYear: Long) : ReportVisitable {
        override fun accept(visitor: ReportVisitor) = visitor.visit(this)
    }

    class TimeAndMaterialsContract(val costPerHour: Long, val hours: Long) : ReportVisitable {
        override fun accept(visitor: ReportVisitor) = visitor.visit(this)
    }

    class SupportContract(val costPerMonth: Long) : ReportVisitable {
        override fun accept(visitor: ReportVisitor) = visitor.visit(this)
    }

    interface ReportVisitor {
        fun visit(contract: FixedPriceContract)
        fun visit(contract: TimeAndMaterialsContract)
        fun visit(contract: SupportContract)
    }

    class MonthlyCostReportVisitor(var monthlyCost: Long = 0) : ReportVisitor {
        override fun visit(contract: FixedPriceContract) {
            monthlyCost += contract.costPerYear / 12
        }

        override fun visit(contract: TimeAndMaterialsContract) {
            monthlyCost += contract.costPerHour * contract.hours
        }

        override fun visit(contract: SupportContract) {
            monthlyCost += contract.costPerMonth
        }
    }
使用
    val projectAlpha = FixedPriceContract(costPerYear = 10000)
    val projectBeta = SupportContract(costPerMonth = 500)
    val projectGamma = TimeAndMaterialsContract(hours = 150, costPerHour = 10)
    val projectKappa = TimeAndMaterialsContract(hours = 50, costPerHour = 50)

    val projects = arrayOf(projectAlpha, projectBeta, projectGamma, projectKappa)

    val monthlyCostReportVisitor = MonthlyCostReportVisitor()
    projects.forEach { it.accept(monthlyCostReportVisitor) }
    println("Monthly cost: ${monthlyCostReportVisitor.monthlyCost}")
输出
Monthly cost: 5333

Github地址:Kotlin 设计模式
更多内容欢迎关注Kotlin学习网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值