模式 / 行为模式
image

protocol Element {
    func accept(_ v: CarVisitor)
}

//ConcreteElement
class EngineElement {
    func accept(_ v: CarVisitor) {
        v.visit(self)
    }
}

//ConcreteElement
class WheelElement {
    private(setvar number: Int

    init(_ number: Int) {
        self.number = number
    }

    func accept(_ v: CarVisitor) {
        v.visit(self)
    }
}

//ConcreteElement
class CarElement {
    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 TestCarVisitorCarVisitor {
    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 RepairCarVisitorCarVisitor {
    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)