Patterns / Behavioral patterns
image

# ConcreteElement
class Engine
    def accept(v)
        v.visit_engine(self)
    end
end

# ConcreteElement
class Wheel
    attr_reader :number

    def initialize(number)
        @number = number
    end

    def accept(v)
        v.visit_wheel(self)
    end
end

# ConcreteElement
class Car
    def initialize()
        @items = [
            Engine.new,
            Wheel.new(1), Wheel.new(2),
            Wheel.new(3), Wheel.new(4)]
    end

    def accept(v)
        @items.each{ |e| e.accept(v) }
        v.visit_car(self)
    end
end

# ConcreteVisitor
class ScanCarVisitor
    def visit_engine(engine)
        puts "scan engine"
    end

    def visit_wheel(wheel)
        puts "scan wheel #" +
              wheel.number.to_s
    end

    def visit_car(car)
        puts "scan car"
    end
end

# ConcreteVisitor
class RepairCarVisitor
    def visit_engine(engine)
        puts "repair engine"
    end

    def visit_wheel(wheel)
        puts "repair wheel #" +
              wheel.number.to_s
    end

    def visit_car(car)
        puts "repair car"
    end
end

# Client
testCar = Car.new
v1 = ScanCarVisitor.new
v2 = RepairCarVisitor.new

testCar.accept(v1)
testCar.accept(v2)


Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.