Kotlin Design Pattern: Visitor

2017-12-18  本文已影响0人  ParanoidMarvern

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

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

 **/
上一篇 下一篇

猜你喜欢

热点阅读