Search code examples
javadesign-patternscastingvisitor-pattern

Is there a way to avoid using method for self invoke inside every element in Visitor Pattern?


interface ICarElementVisitor {
    void visit(Engine engine);
}

interface ICarElement {
    //want to use this
    void accept(ICarElementVisitor visitor); // CarElements have to provide accept().
}

static class Engine implements ICarElement {
    ...
    //want to avoid using this
    public void accept(ICarElementVisitor visitor) {
        visitor.visit(this);
    }
}
...
public void accept(ICarElementVisitor visitor) {
    for (ICarElement elem : elements) {
        elem.accept(visitor);
    }
    visitor.visit(this);
}
    ...
static class CarElementDoVisitor implements ICarElementVisitor {

    public void visit(Engine engine) {
        System.out.println("Starting my engine");
    }

}

Is there a way to avoid using method for self invoke inside every element in Visitor Pattern and use global method of parent class? Or if can i pass parent object and know what instance is that object without instanceof if or switch?


Solution

  • I think you have to do that to be sure to have the corresponding visit() method for all the ICarElement in all ICarElementVisitor

    So if you write an new ICarElement, let say IWheel, one year later and you don't remember all visitors already existing you will be oblige to implement the accept(ICarElementVisitor) method doing visitor.visit(this); doing that the complier will say: "there is no method visit(IWheel) in ICarElementVisitor!" so you will add the visit(IWheel) in the ICarElementVisitor interface and the compiler will say "CarElementDoVisitor don't implement all methods of ICarElementVisitor!" and you will implement visit(IWheel) in CarElementDoVisitor so you are sure to avoid regression.

    I think that the point of doing that and it's not useless, in fact that a good thing.