美文网首页
Kotlin Design Pattern: Visitor

Kotlin Design Pattern: Visitor

作者: ParanoidMarvern | 来源:发表于2017-12-18 21:36 被阅读0次

The visitor pattern is used to separate a relatively complex set of structured data classes from the functionality that may be performed upon the data that they hold.

Setup

  • Visitor:
    Declare a Visite operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the element directly through particular interface.
  • Concrete Visitor
    Implement each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class of object in the structure. ConcreteVisitor provides the context for the algorithm and stores the local state. This states often accumulates results during the traversal of the structure.
  • Element
    Define an accept operation which takes a visitor as argument.
  • Concrete Element
    Implement the operation that takes a visitor as argument.
  • Client

Example 1

// Step 5: Client code

fun main(args: Array<String>) {
    val oneVisitor = OneVisitor()
    val sightSeeing = SightSeeing()

    sightSeeing.accept(oneVisitor)
}

// Step 1: Visitable Interface (Element interface)

interface Visitable{
    fun accept(visitor: Visitor)
}

// Step 2: Concrete Visitable (Concrete Element)

class Palace: Visitable{
    override fun accept(visitor: Visitor) {
        visitor.visit(this)
    }
}

class Museum: Visitable{
    override fun accept(visitor: Visitor) {
        visitor.visit(this)
    }
}

class Monument: Visitable{
    override fun accept(visitor: Visitor) {
        visitor.visit(this)
    }
}

class SightSeeing: Visitable{
    private val visitable = arrayOf(Palace(), Museum(), Monument())
    override fun accept(visitor: Visitor) {
        for (v in visitable)
            v.accept(visitor)
    }
}

// Step 3: Visitor Interface

interface Visitor{
    fun visit(visitable: Visitable)
    fun visit(visitable: Palace)
    fun visit(visitable: Museum)
    fun visit(visitable: Monument)
}

// Step 4: Concrete Visitor

class OneVisitor: Visitor{
    override fun visit(visitable: Visitable) {
        println("I am visiting ${visitable.javaClass.simpleName}")
    }

    override fun visit(visitable: Monument) {
        println("I am visiting ${visitable.javaClass.simpleName}")
    }

    override fun visit(visitable: Museum) {
        println("I am visiting ${visitable.javaClass.simpleName}")
    }

    override fun visit(visitable: Palace) {
        println("I am visiting ${visitable.javaClass.simpleName}")
    }
}

/**
        prints

        I am visiting Palace
        I am visiting Museum
        I am visiting Monument
        
 **/

Example 2

// Step 5: Client code

fun main(args: Array<String>) {
    val customer = OneCustomer()

    val shopList = arrayOf(Toothpaste(2), Tissues(6), Lotion(1))

    shopList.forEach { it.accept(customer) }

    println("Sum = ${customer.sum}")
}

// Step 1: Visitable Interface

interface Commodity{
    fun accept(visitor: Customer)
}

// Step 2: Concrete Visitable

class Toothpaste(private val quantity: Int): Commodity{
    override fun accept(visitor: Customer) {
        println("Article: ${this.javaClass.simpleName}, Quantity: $quantity")
        visitor.visit(visitable = this, quantity = quantity)
    }
}

class Tissues(private val quantity: Int): Commodity{
    override fun accept(visitor: Customer) {
        println("Article: ${this.javaClass.simpleName}, Quantity: $quantity")
        visitor.visit(visitable = this, quantity = quantity)
    }
}

class Lotion(private val quantity: Int): Commodity{
    override fun accept(visitor: Customer) {
        println("Article: ${this.javaClass.simpleName}, Quantity: $quantity")
        visitor.visit(visitable = this, quantity = quantity)
    }
}

// Step 3: Visitor Interface

interface Customer{
    fun visit(visitable: Toothpaste, quantity: Int)
    fun visit(visitable: Tissues, quantity: Int)
    fun visit(visitable: Lotion, quantity: Int)
}

// Step 4: Concrete Visitor

class OneCustomer: Customer{
    var sum: Int = 0

    override fun visit(visitable: Lotion, quantity: Int) {
        sum += quantity * 30
    }

    override fun visit(visitable: Tissues, quantity: Int) {
        sum += quantity * 10
    }

    override fun visit(visitable: Toothpaste, quantity: Int) {
        sum += quantity * 15
    }
}

/**
        prints

        Article: Toothpaste, Quantity: 2
        Article: Tissues, Quantity: 6
        Article: Lotion, Quantity: 1
        Sum = 120

 **/

相关文章

网友评论

      本文标题:Kotlin Design Pattern: Visitor

      本文链接:https://www.haomeiwen.com/subject/iagpwxtx.html