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()
}
相关推荐
xiangpanf7 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx10 小时前
安卓线程相关
android
消失的旧时光-194310 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon11 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon11 小时前
VSYNC 信号完整流程2
android
dalancon11 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户693717500138412 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
敲代码的约德尔人13 小时前
JavaScript 设计模式完全指南
javascript·设计模式
程序员Android13 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才13 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android