行为型模式
在软件工程中, 行为型设计模式是用来确认对象之间的公共的交流模式的。通过这样做,这些模式提高了实现这种交流的灵活性。
举例:
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) } }
输出
Text is changed to: Lorem ipsum Text is changed to: dolor sit amet
策略模式
策略模式一般用来创建一个可替换的算法簇,在运行时决定需要什么。
使用
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")
举例:
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() } }
输出
adding order with id: 1adding order with id: 2paying for order with id: 2paying for order with id: 1
状态模式
状态模式一般用来在对象内部的状态发生改变时,更改这个对象的行为。这个模式允许在运行时显示的更改一个对象的类。
<a target="_blank title=" null"="" href="https://github.com/dbacinski/Design-Patterns-In-Kotlin#example-3" style="word-wrap: break-word; color: rgb(59, 67, 72);">举例:
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" } }
输出
User 'admin' is logged in: trueUser 'Unknown' is logged in: false
责任链模式
责任链模式通常用来处理多变的请求,每个请求可能交由不同的处理者进行处理。
<a target="_blank title=" null"="" href="https://github.com/dbacinski/Design-Patterns-In-Kotlin#example-4" style="word-wrap: break-word; color: rgb(59, 67, 72);">举例:
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 } }
输出
Message with Authentication:Authorization: Bearer 123456ContentType: json{"username"="dbacinski"}
访问者模式
访问者模式通常用来将结构相对复杂的数据类从功能(根据它们所持有的数据来执行)中分离出来。
使用
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}")