Kotlin设计模式与示例:进阶篇
在初级阶段,开发者会掌握经典的设计模式:单例模式、工厂模式、观察者模式。然而,在构建复杂、可扩展的系统时,需要更精细的架构调整。本文将讲解Kotlin中的四种进阶设计模式:组合模式、访问者模式、状态模式和桥接模式。每种模式都将通过实际代码示例和适用场景说明进行阐述。
1. 组合模式 (Composite)
组合模式允许客户端以统一的方式处理单个对象和对象组合。这是构建层次结构(如文件系统、界面菜单或图形场景)的理想解决方案。
在Kotlin中,我们经常使用密封类来表示树节点。来看一个构建"文件和文件夹"结构的例子:
sealed class FileSystemNode(open val name: String) {
data class File(override val name: String, val size: Long) : FileSystemNode(name)
data class Directory(
override val name: String,
val children: MutableList<FileSystemNode> = mutableListOf()
) : FileSystemNode(name) {
fun add(node: FileSystemNode) {
children.add(node)
}
fun remove(node: FileSystemNode) {
children.remove(node)
}
fun getTotalSize(): Long = children.sumOf {
when (it) {
is File -> it.size
is Directory -> it.getTotalSize()
}
}
}
}
// 使用示例
fun main() {
val root = FileSystemNode.Directory("root")
root.add(FileSystemNode.File("readme.txt", 1024))
val subDir = FileSystemNode.Directory("src")
subDir.add(FileSystemNode.File("main.kt", 4096))
root.add(subDir)
println("总大小: ${root.getTotalSize()} 字节") // 5120
}
优点:简化客户端代码,支持递归操作。缺点:如果树结构过深,可能使系统变得复杂。
2. 访问者模式 (Visitor)
访问者模式允许在不修改对象类的情况下,为对象添加新的操作。当您拥有稳定的类层次结构但处理算法频繁变化时,此模式特别有用。
在Kotlin中,它与密封类配合得很好。我们来实现一个计算图形面积的例子:
sealed class Shape
class Circle(val radius: Double) : Shape()
class Rectangle(val width: Double, val height: Double) : Shape()
interface ShapeVisitor<T> {
fun visit(circle: Circle): T
fun visit(rectangle: Rectangle): T
}
class AreaCalculator : ShapeVisitor<Double> {
override fun visit(circle: Circle) = Math.PI * circle.radius * circle.radius
override fun visit(rectangle: Rectangle) = rectangle.width * rectangle.height
}
// 使用示例
fun <T> Shape.accept(visitor: ShapeVisitor<T>): T = when (this) {
is Circle -> visitor.visit(this)
is Rectangle -> visitor.visit(this)
}
fun main() {
val shapes = listOf(Circle(5.0), Rectangle(3.0, 4.0))
val calculator = AreaCalculator()
shapes.forEach { println("面积: ${it.accept(calculator)}") }
}
适用场景:对象结构很少变化,但对其进行的操作频繁变化。在Kotlin中,对于简单情况可以使用when表达式,但访问者模式在处理包含多种类型的复杂逻辑时仍然不可或缺。
3. 状态模式 (State)
状态模式允许对象根据其内部状态改变自身行为。这是冗长的if-else或switch-case语句的优雅替代方案。
在Kotlin中,我们可以使用密封类来表示状态。以在线商店的订单为例: