[GO] [Gang of Four] Design pattern learning --Visitor

Visitor-Visitor

** Table of Contents ** I understand that the pattern is to provide the visitor with an interface for all the elements and let the visitor handle the processing related to that element.

Purpose

Represents an operation performed on an element on an object structure. The Visitor pattern allows you to define a new operation without changing the class of the object you are adding the operation to.

Component

・ Visitor visitor abstract class ・ ConcreteVisitor Visitor concrete class -Element Abstract class of elements that transfer processing to visitors -ConcreteElement A concrete class of elements that transfer processing to a visitor -A class that can enumerate ObjectStructure elements (it seems, but I don't understand the necessity)

Implementation

Implement a program to cook dishes using the prepared ingredients.

Visitor visitor abstract class

Visitor.kt


package visitor

interface Visitor {
    fun visit(e: PotatoElement)
    fun visit(e: CarrotElement)
    fun visit(e: PorkElement)
    fun visit(e: OtherElement)
    fun serve()
}

ConcreteVisitor Visitor concrete class

Visitors making curry

CurryVisitor.kt


package visitor

class CurryVisitor: Visitor {
    private var cookingPotato = false
    private var cookingCarrot = false
    private var cookingPork = false
    private var cookingOther = false

    override fun visit(e: PotatoElement) {
        cookingPotato = true
        println("${e.name()}Peel and cut and simmer in a pan.")
    }

    override fun visit(e: CarrotElement) {
        cookingCarrot = true
        println("${e.name()}Take the sprouts, peel and cut and simmer in a pot.")
    }

    override fun visit(e: PorkElement) {
        cookingPork = true
        println("${e.name()}Cut and simmer in a pan.")
    }

    override fun visit(e: OtherElement) {
        cookingOther = true
        println("With curry roux${e.name()}Put in a pan and simmer.")
    }

    override fun serve() {
        if (cookingPotato && cookingCarrot && cookingOther && cookingPork) {
            println("Completion of curry!")
        } else {
            println("I'm still cooking.")
        }
    }

}

Element Abstract class of elements that transfer processing to the visitor

Material abstract class

Element.kt


package visitor

interface Element {
    fun name(): String
    fun cooking(v: Visitor)
}

ConcreteElement A concrete class of elements that transfer processing to the visitor

Material concrete classes Potatoes

PotatoElement.kt


package visitor

class PotatoElement: Element {
    override fun name(): String {
        return "Potatoes"
    }

    override fun cooking(v: Visitor) {
        v.visit(this)
    }
}

Carrots

CarrotElement.kt


package visitor

class CarrotElement: Element {
    override fun name(): String {
        return "Carrots"
    }

    override fun cooking(v: Visitor) {
        v.visit(this)
    }
}

pork

PorkElement.kt


package visitor

class PorkElement: Element {
    override fun name(): String {
        return "pork"
    }

    override fun cooking(v: Visitor) {
        v.visit(this)
    }

}

Other

OtherElement.kt


package visitor

class OtherElement: Element {
    override fun name(): String {
        return "Salt and pepper"
    }

    override fun cooking(v: Visitor) {
        v.visit(this)
    }
}

People who use

Client.kt


package visitor

class Client {
    init {
        serveCurry()
    }

    private fun serveCurry() {
        val pot = PotatoElement()
        val c = CarrotElement()
        val por = PorkElement()
        val o = OtherElement()
        val v = CurryVisitor()

        pot.cooking(v)
        c.cooking(v)
        por.cooking(v)
        v.serve()
        o.cooking(v)
        v.serve()
    }
}
[out-put]

Peel the potatoes, cut them and simmer in a pan.
Take the carrot sprouts, peel and cut and simmer in a pan.
Cut the pork and simmer in a pan.
I'm still cooking.
Put curry roux, salt and pepper in a pan and simmer.
Completion of curry!

I want to make stir-fried vegetables, so I will implement Fried Vegetables Visitor.

FriedVegetablesVisitor.kt


package visitor

class FriedVegetablesVisitor: Visitor {
    private var cookingPotato = false
    private var cookingCarrot = false
    private var cookingPork = false
    private var cookingOther = false

    override fun visit(e: PotatoElement) {
        cookingPotato = true
        println("${e.name()}Peel, cut and fry.")
    }

    override fun visit(e: CarrotElement) {
        cookingCarrot = true
        println("${e.name()}Take the sprouts, peel and cut and fry.")
    }

    override fun visit(e: PorkElement) {
        cookingPork = true
        println("${e.name()}Cut and fry.")
    }

    override fun visit(e: OtherElement) {
        cookingOther = true
        println("${e.name()}Put in a pan and fry.")
    }

    override fun serve() {
        if (cookingPotato && cookingCarrot && cookingOther && cookingPork) {
            println("Completion of stir-fried vegetables!")
        } else {
            println("I'm still cooking.")
        }
    }
}

Client.kt


package visitor

class Client {
    init {
        serveCurry()
        println("--------------------------------")
        serveFriedVegetables()
    }

    private fun serveFriedVegetables() {
        val pot = PotatoElement()
        val c = CarrotElement()
        val por = PorkElement()
        val o = OtherElement()
        val v = FriedVegetablesVisitor()

        pot.cooking(v)
        c.cooking(v)
        por.cooking(v)
        v.serve()
        o.cooking(v)
        v.serve()
    }

    private fun serveCurry() {
        val pot = PotatoElement()
        val c = CarrotElement()
        val por = PorkElement()
        val o = OtherElement()
        val v = CurryVisitor()

        pot.cooking(v)
        c.cooking(v)
        por.cooking(v)
        v.serve()
        o.cooking(v)
        v.serve()
    }
}

Output result

[out-put]
Peel the potatoes, cut them and simmer in a pan.
Take the carrot sprouts, peel and cut and simmer in a pan.
Cut the pork and simmer in a pan.
I'm still cooking.
Put curry roux, salt and pepper in a pan and simmer.
Completion of curry!
--------------------------------
Peel the potatoes, cut them and fry them.
Take the carrot sprouts, peel and fry.
Cut the pork and fry.
I'm still cooking.
Put salt and pepper in a pan and fry.
Completion of stir-fried vegetables!

Recommended Posts

[Gang of Four] Design pattern learning --Visitor
[Gang of Four] Design pattern learning
[Gang of Four] Design pattern learning --Singleton
[Gang of Four] Design Pattern Learning --Decorator
[Gang of Four] Design pattern learning --Mediator
[Gang of Four] Design pattern learning --Iterator
[Gang of Four] Design pattern learning --Facade
[Gang of Four] Design pattern learning --Composite
[Gang of Four] Design pattern learning --Prototype
[Gang of Four] Design pattern learning --Memento
[Gang of Four] Design pattern learning --State
[Gang of Four] Design pattern learning --Interpreter
[Gang of Four] Design pattern learning --Builder
[Gang of Four] Design pattern learning --Bridge
[Gang of Four] Design pattern learning --Proxy
[Gang of Four] Design pattern learning --Strategy
[Gang of Four] Design pattern learning --Adapter
[Gang of Four] Design pattern learning --Observer
[Gang of Four] Design pattern learning --Command
[Gang of Four] Design pattern learning --Abstract Factory
[Gang of Four] Design pattern learning --Factory Method
[Gang of Four] Design pattern learning --Chain of Responsibility
[Gang of Four] Design pattern learning --Template Method
Learn the design pattern "Visitor" in Python
Gang of Four (GoF) Patterns in Python
Design Pattern #Builder
Design Pattern #Adapter
Design Pattern #Decorator
Pattern recognition learning in video Part 1 Field of Pattern Recognition
Design Pattern #Observer
Design Pattern #Facade
Design Pattern #Strategy
Design Pattern #Singleton
Design Pattern #Proxy
Learn the design pattern "Chain of Responsibility" in Python
Design Pattern #Factory Method
Visitor pattern in Python
Deep learning 1 Practice of deep learning
Design Pattern #Template Method
About the Visitor pattern
GoF design pattern is just an "introduction of abstraction layer"