** 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.
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.
・ 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)
Implement a program to cook dishes using the prepared ingredients.
Visitor.kt
package visitor
interface Visitor {
fun visit(e: PotatoElement)
fun visit(e: CarrotElement)
fun visit(e: PorkElement)
fun visit(e: OtherElement)
fun serve()
}
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.")
}
}
}
Material abstract class
Element.kt
package visitor
interface Element {
fun name(): String
fun cooking(v: 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)
}
}
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()
}
}
[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