Kotlin之策略模式和状态模式

在本博客中,我们将简短介绍如何在Kotlin中实现策略和状态模式。由于这两种模式在软件行业中都是众所周知的,因此我们不会讨论它们的优缺点,因为这种情况已经被做过数百次了。本示例将直接使用教科书《设计模式 :可重用面向对象软件的元素》中的示例。鼓励阅读这本书,因为它为软件行业带来了很多有价值的内容。

策略模式与状态模式密切相关。因此,我们将在同一篇博客一起介绍它们。

1、策略模式

当今软件最常见的模式之一是所谓的策略模式。它被称为"政策模式"。由于其简单性,大多数开发人员都很容易理解。此外,它还有助于实现符合面向对象设计的SOLID原则的可扩展软件解决方案。

定义一系列算法,封装每个算法,并使它们可以互换。策略使算法能够独立于使用它的客户端而变化。
GoF,设计模式

1.1、示例说明

当客户对同一问题使用不同的算法时,可以使用此模式。经常发生的问题之一是将文本流(例如大字符串)分解为较小的字符串。我们称之为换行算法。根据上下文,人们可能会使用不同的算法。使用代码的客户不应该依赖于具体的实现。

我们将每个算法封装到一个单独的类中(称为策略)。这些类中的每一个都必须实现某个接口,该接口将由客户端(直接或间接)使用。

在我们的例子中,我们将处理三种不同的算法SimpleCompositorTeXCompositorArrayCompositor。客户端类(Composition)将使用抽象类Compositor。下面的UML图说明了类设置。

1.2、Kotlin中的实现

为了在Kotlin中实现上述示例,我们将使用抽象接口Compositor。所有用作算法的类都必须实现此接口。

kotlin 复制代码
interface Compositor {
    fun compose()
}

class SimppleCompositor: Compositor {
    override fun compose() {
        println("SimpleCompositor::compose")
    }
}

class TeXCompositor: Compositor {
    override fun compose() {
        println("TeXCompositor::compose")
    }
}

class ArrayCompositor: Compositor {
    override fun compose() {
        println("ArrayCompositor::compose")
    }
}

class Composition(private var compositor: Compositor) {
    fun traverse() {
        compositor.compose()
    }
    
    fun repair() {
        compositor.compose()
    }
}

fun main() {
    val teXCompositor = TeXCompositor()
    val composition = Composition(texCompositor)
    composition.repair()
}

2、状态模式

这种模式与策略模式密切相关。我们希望能够在对象的状态发生变化时改变其行为。这种行为变化对于将使用该类的客户端来说应该是透明的。

允许对象在其内部状态发生变化时改变其行为。该对象似乎会更改其类。

GoF------设计模式

2.1、示例说明

考虑一个TCPConnection表示TCP网络连接的类。它可以有多种状态,例如EstablishedListenClosed。根据不同的状态,它的工作(行为)会有所不同。我们将把每个状态(及其功能)封装在一个类中。所有类(状态)都必须实现抽象类提供的接口TCPState。下面的UML图说明了类设置。

请注意,与原始设计相反,我们TCPConnection还实现了TCPState

2.2、Kotlin中的实现

该模式的实现方式与前面的示例类似。我们将使用提供函数声明的抽象接口。所有状态都将实现该接口。该类TCPConnection有一个状态成员,并将所有函数调用直接委托给其状态。

请注意,我们不能使用Kotlin内置的委托模式。如教程所述,一旦将委托分配得对象,当前就无法更改委托。换句话说,我们无法使用此模式更改状态。这意味着我们必须手动实现该接口。

kotlin 复制代码
interface TCPState {
    fun open()
    fun clone()
    fun acknowledge()
}

class TCPEstablished: TCPState {
    override fun open() {
        println("TCPEstablished::open")
    }
    
    override fun close() {
        println("TCPEstablished::close")
    }
    
    override fun acknowledge() {
        println("TCPEstablished::acknowledge")
    }
}

class TCPListen: TCPState {
    override fun open() {
        println("TCPListen::open")
    }
    
    override fun close() {
        println("TCPListen::close")
    }
    
    override fun acknowledge() {
        println("TCPListen::acknowledge")
    }
}

class TCPClosed: TCPState {
    override fun open() {
        println("TCPClosed::open")
    }
    
    override fun close() {
        println("TCPClosed::close")
    }
    
    override fu acknowledge() {
        println("TCPClosed::acknowledge")
    }
}

class TCPConnection: TCPState {
    private var state: TCPState = TCPListen()
    
    override fun open() {
        state.open()
    }
    
    override fun close() {
        state.close()
    }
    
    override fun acknowledge() {
        state.acknowledge()
    }
    
    fun changeState() {
        // other state
    }
}

fun main() {
    val connection = TCPConnection()
    connection.open()
    connection.changeState()
}
相关推荐
萌面小侠Plus几秒前
Android笔记(三十三):封装设备性能级别判断工具——低端机还是高端机
android·性能优化·kotlin·工具类·低端机
慢慢成长的码农1 分钟前
Android Profiler 内存分析
android
大风起兮云飞扬丶1 分钟前
Android——多线程、线程通信、handler机制
android
L72568 分钟前
Android的Handler
android
清风徐来辽8 分钟前
Android HandlerThread 基础
android
HerayChen1 小时前
HbuildderX运行到手机或模拟器的Android App基座识别不到设备 mac
android·macos·智能手机
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
hairenjing11231 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
小黄人软件2 小时前
android浏览器源码 可输入地址或关键词搜索 android studio 2024 可开发可改地址
android·ide·android studio
dj15402252032 小时前
group_concat配置影响程序出bug
android·bug