Die Besuchervorlage ist für Kotlin veraltet, aber es lohnt sich zu wissen

Betrachten Sie das Besucherentwurfsmuster und zeigen Sie, dass Sie es beim Programmieren auf Kotlin nicht verwenden sollten. Es wird eine Theorie, eine minimalistische Implementierung, die Implementierung eines Ersatzes und die Argumente für einen Ersatz geben, die durch praktische Forschung gestützt werden. Es werden keine Klassendiagramme angezeigt. Sie können alles online unter play.kotlinlang.org ausprobieren



Auf meinem extrem , JSON . Finite State Machine, Visitor. State Machine , Visitor, — "!". , , . — , , . — , . — .



Visitor. . , LinkedIn , , . Visitor , ( ). Hollywood Agent — " — ". - . , . Python JavaScript . "", — — , . Java .


, , ( ) . , , ( ), . — . Kotlin " " , ( , ).


— Visitor . Visitor , , . , , , , . , , , , . Visitor.



, : . sealed class , .
: .


fun main() {
    Guest().visit( Human(""))
    Guest().visit( Cat(""))
}

sealed class LivingCreature
class Human(val name: String): LivingCreature()
class Cat(val colour: String): LivingCreature()

interface Visitor {
    fun visit(creature : Human)
    fun visit(creature : Cat)
}
class Guest: Visitor {
    override fun visit(human: Human) = println("  ${human.name}")
    override fun visit(pet: Cat) = println("  (  ${pet.colour})")
}

— . , visit . , Human Cat LivingCreature. :


fun main() {
    val human: LivingCreature = Human("")
    val cat  : LivingCreature = Cat("")
    Guest().visit( human) 
    Guest().visit( cat )
}

sealed class LivingCreature
class Human(val name: String): LivingCreature()
class Cat(val colour: String): LivingCreature()

interface Visitor {
    fun visit(creature : Human)
    fun visit(creature : Cat)
}
class Guest: Visitor {
    override fun visit(human: Human) = println("  ${human.name}")
    override fun visit(pet: Cat) = println("  (  ${pet.colour})")
}

, visit(LivingCreature). , , — , , . , , .


Visitor. , , — Human Cat, , Guest (Visitor) . LivingCreature Visitor visit, .


fun main() {
    val human: LivingCreature = Human("")
    val cat  : LivingCreature = Cat("")
    human.accept( Guest() ) //   LivingCreature.accept( Visitor ),         
    cat.accept( Guest() ) // 
}

sealed class LivingCreature {
    abstract fun accept(visitor: Visitor) //    inline fun -     
}
interface Visitor {
    fun visit(creature : Human)
    fun visit(creature : Cat)
}
class Human(val name: String): LivingCreature() {
    override fun accept(visitor: Visitor) = visitor.visit(this) //    Human,    visit(Human)  -
}
class Cat(val colour: String): LivingCreature(){
    override fun accept(visitor: Visitor) = visitor.visit(this) //    Cat,    visit(Cat)  -
}

class Guest : Visitor{
    override fun visit(creature : Human) = println("  ${creature.name}")
    override fun visit(creature : Cat) = println("  (  ${creature.colour})")
}

inline fun , - .
visit , — ( ) . accept, — . Visitor.


— . . — accept. , . , — . Visitor.


, Visitor — , - .


" "?


LivingCreature Visitor.visit(LivingCreature)?


fun main() {
    val human: LivingCreature = Human("")
    val cat  : LivingCreature = Cat("")
    Guest().visit(human )
    Guest().visit( cat )
}

sealed class LivingCreature 
interface Visitor {
    fun visit(creature: LivingCreature)
}
class Human(val name: String): LivingCreature()
class Cat(val colour: String): LivingCreature()

class Guest : Visitor{
    override fun visit(creature : LivingCreature) = when(creature) {
        is Human -> println( "  ${creature.name}")
        is Cat -> println( "  (  ${creature.colour} ) ")
    }
}

, , . . ? , Java instanceof , , , JVM — Java. - — ++. "" . - , instanceof , JVM. , JVM .


Es stellt sich heraus, dass Sie Kotlin- und Java-Leistungstests in JHM schreiben können , was ich auch getan habe. Das Ergebnis hat mich überrascht - die Version mit Visitor arbeitet um ein Vielfaches langsamer als die Version mit when / smart cast . Sie können es hier sehen:
mein Repository auf GitHub


Ergebnisse


  • Besucher sind eine großartige Übung für den Verstand, und ich würde es wärmstens empfehlen, sie in unerwarteten Situationen zu versuchen, aber aus akademischem Interesse.
  • Der Besucher verbessert den visuellen Java-Code und ermöglicht es Ihnen, das Verhalten klarer auszudrücken. Eine gute Option für Generatoren, Event-Handler-Muster (siehe ANTLR).
  • Der Besucher verliert aufgrund der Besonderheiten der Sprache an Lesbarkeit und Leistung gegenüber der „naiven“ Lösung auf Kotlin.

All Articles