
protocol Element {
func accept(_ v: CarVisitor)
}
//ConcreteElement
class Engine: Element {
func accept(_ v: CarVisitor) {
v.visit(self)
}
}
//ConcreteElement
class Wheel: Element {
private(set) var number: Int
init(_ number: Int) {
self.number = number
}
func accept(_ v: CarVisitor) {
v.visit(self)
}
}
//ConcreteElement
class Car: Element {
let items: [Element] = [
Engine(),
Wheel(1), Wheel(2),
Wheel(3), Wheel(4)]
func accept(_ v: CarVisitor) {
for e in items {
e.accept(v)
}
v.visit(self)
}
}
//Visitor
protocol CarVisitor {
func visit(_ engine: Engine)
func visit(_ wheel: Wheel)
func visit(_ car: Car)
}
//ConcreteVisitor
class TestCarVisitor: CarVisitor {
func visit(_ engine: Engine) {
print("test engine")
}
func visit(_ wheel: Wheel) {
print("test wheel #\(wheel.number)")
}
func visit(_ car: Car) {
print("test car")
}
}
//ConcreteVisitor
class RepairCarVisitor: CarVisitor {
func visit(_ engine: Engine) {
print("repair engine")
}
func visit(_ wheel: Wheel) {
print("repair wheel #\(wheel.number)")
}
func visit(_ car: Car) {
print("repair car")
}
}
//Client
let car = Car()
let v1 = TestCarVisitor()
let v2 = RepairCarVisitor()
car.accept(v1)
car.accept(v2)