在Kotlin中实现访客模式的最佳方式

Max*_*Max 4 design-patterns kotlin

在Kotlin中实施访客模式是否有任何技巧或常用方法?任何对初学者来说都不明显的东西,但会导致更简洁或有组织的代码.

编辑澄清:我有一个AST,其中有许多(~30)类型的节点.目前,每个类都实现了自己的print()方法,我想将其分解为一个单独的Printer类.随着访问者模式的到位,添加其他AST遍历类会更加清晰,其中会有几个.

Jay*_*ard 6

阅读Java 8的答案,它所说的一切也适用于Kotlin:

对Java语言的添加并没有使每个旧概念过时.事实上,访客模式非常擅长支持添加新操作.

这对Kotlin来说也是如此.与Java 8一样,它具有Lambdas,SAM转换允许默认实现的接口.

一个变化是,如果您正在进行类实例类型检查,而不是if对每个instanceof检查使用大语句,请使用Kotlin中的when表达式:

在不同答案的同一个Stackoverflow页面上,它讨论了正在使用的Lambdas,并if在Java中显示语句,决定调用哪个lambda.而不是他们的Java示例:

if (animal instanceof Cat) {
    catAction.accept((Cat) animal);
} else if (animal instanceof Dog) {
    dogAction.accept((Dog) animal);
} else if (animal instanceof Fish) {
    fishAction.accept((Fish) animal);
} else if (animal instanceof Bird) {
    birdAction.accept((Bird) animal);
} else {
    throw new AssertionError(animal.getClass());
}
Run Code Online (Sandbox Code Playgroud)

使用这个Kotlin:

when (animal) {
    is Cat -> catAction.accept(animal)
    is Dog -> dogAction.accept(animal)
    is Fish -> fishAction.accept(animal)
    is Bird -> birdAction.accept(animal)
    else -> throw AssertionError(animal.javaClass)
}
Run Code Online (Sandbox Code Playgroud)

在科特林你不需要投因为智能施法,当编译器看到的是自动进行is的实例类型检查.

同样在Kotlin中,您可以使用密封类来表示层次结构中可能的选项,然后编译器可以确定您是否已用尽所有情况,这意味着您不需要elsewhen语句中使用.

否则在该页面上的内容是正确的,同一问题的其他常见答案是Kotlin的良好信息.我认为在Java 8,Scala或Kotlin中看到实际的文字访问者模式并不常见,而是使用lambda和/或模式匹配来看一些变体.

其他相关文章:

  • 使用大的 if-else/when 子句进行类型检查是访问者模式试图避免的,不是吗?因此,只有第二篇相关文章([phd-in](http://amrphd.blogspot.com.uy/2014/12/visitor-design-pattern-vs-lambda.html))中的解决方案似乎是有效,因为那里使用了单一调度。但是使用包含 n 个 lambda 的接受方法而不是一个访问者对象听起来也不合理。如果您无权访问要双重分派的类,则问题会变得更加明显。然后您使用静态分派的扩展方法,或者...... (4认同)