专业的编程技术博客社区

网站首页 > 博客文章 正文

Kotlin设计模式:访问者模式(kotlin inner)

baijin 2024-10-01 07:32:40 博客文章 8 ℃ 0 评论

访问者模式的目的

从对象结构中分离算法。将访问者视为访问多个地方并根据地方不同而做不同事情的人。这意味着需要修改访问者而不是地方本身。

它主要用于实现在对象内部没有意义但对新功能的工作是必需的事物。

可做什么?

  • 开闭原则:可以添加新的算法而不更改对象结构。
  • 单一职责:每个类负责不同的行为。
  • 对类进行扩展,几乎不需要对其进行修改。
  • 避免污染对象类。

最大的缺点是,当从层次结构中添加或删除类时,必须更新所有访问者。

实现

在图中,我们有访问者,它有访问Element的具体实现的方法,因此它依赖于每个Element实现。

同时,Element依赖于访问者接口。这样做是为了避免每次想要使用访问者时都检查Element的类型,代替这个,会接受访问者并在Element内部使用正确的方法。该方法将是一个一行的方法,调用正确的访问者方法。

此外,能够创建多个ConcreteVisitors,它们可以做不同的事情。

示例

任务是向健康系统添加导出为CSV功能。考虑添加其他导出选项。向Body添加函数看起来至少有些奇怪,它应该是分开的。

这是访问者的完美用例,因为我们可以轻松添加新的导出选项而不干扰太多body健康系统。如何构建代码:

在真实应用中BodyPart也会有其他功能,这里示例中只是保持简单。开始编码BodyPartsVisitor接口:

interface Visitor {
    fun visitEye(eye: Eye)
    fun visitMouth(mouth: Mouth)
}
interface BodyPart {
    fun accept(visitor: Visitor)
}
class Eye(val color: String) : BodyPart {
    override fun accept(visitor: Visitor) {
        visitor.visitEye(this)
    }
}
class Mouth(val size: Int) : BodyPart {
    override fun accept(visitor: Visitor) {
        visitor.visitMouth(this)
    }
}

现在,访问者实现可以访问MouthEye。编写ExportToCSVVisitor

class ExportToCSVVisitor : Visitor {
    override fun visitEye(eye: Eye) {
        println("csv eye: ${eye.color}")
    }
    override fun visitMouth(mouth: Mouth) {
        println("csv mouth: ${mouth.size}")
    }
}

出于简单考虑,EyeMouth只有一个参数,我们将只打印信息。

这是如何使用它的:

fun main() {
    val visitor: Visitor = ExportToCSVVisitor()
    val bodyParts = listOf(
        Eye("blue"),
        Eye("borwn"),
        Mouth(20),
    )
    bodyParts.forEach { it.accept(visitor) }
    // csv eye: blue
    // csv eye: borwn
    // csv mouth: 20
}

使用 Visitor 方法时不需要知道 BodyPart 的类型,因为它们都有 accept 函数来选择正确的 Visitor 功能。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表