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

来源:互联网 发布:python多进程读取文件 编辑:程序博客网 时间:2024/06/03 14:58

行为型模式

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

观察者模式

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

举例:

    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 ipsumText 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 ametLOREM IPSUM DOLOR SIT AMETPrefix: 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: 1adding order with id: 2paying for order with id: 2paying 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: trueUser '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 123456ContentType: 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学习网

原创粉丝点击