O modelo de visitante foi descontinuado para o Kotlin, mas vale a pena conhecer

Considere o padrão de design do Visitor e mostre que você não deve usá-lo ao programar no Kotlin. Haverá uma teoria, uma implementação minimalista, a implementação de uma substituição e os argumentos a favor de uma substituição, respaldados por pesquisas práticas. Não haverá diagramas de classe. Você pode experimentar tudo online em play.kotlinlang.org



No meu extremo , 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 .


Acontece que você pode escrever testes de desempenho Kotlin e Java no JHM , o que eu fiz. O resultado me surpreendeu - a versão com Visitor funciona muitas vezes mais lenta que a versão quando / elenco inteligente . Você pode vê-lo aqui:
meu repositório no GitHub


achados


  • O visitante é um ótimo exercício para a mente e eu recomendo experimentá-lo em situações inesperadas, mas por interesse acadêmico.
  • O Visitor aprimora o código Java visual e permite que você expresse o comportamento com mais clareza. Uma boa opção para geradores, padrões de manipulador de eventos (consulte ANTLR).
  • O visitante perde em legibilidade e desempenho para a solução "ingênua" no Kotlin devido às peculiaridades do idioma.

All Articles