美文网首页
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