javadesign-patternsvisitor-pattern

Could visitor pattern contain some states?


Assume this model class :

public class Car extends Vehicle implements Visitable {
  .....
  void accept(VehicleVisitor visitor){
    visitor.visit(this);
  }  
  .....
}

Use of visitor because the decision to permit certains vehicles to be awarded was made very later (after the creation of Car class).

And a specific hierarchy of Visitor with a base class named VehicleEvaluatorVisitor inheriting from CarVisitor whose goal is to inform whether vehicle merits awards or not :

public class VehicleEvaluatorVisitor implements VehicleVisitor {

  boolean mustBeAwarded;

  public visit(Car car){
    ....
    mustBeAwarded= true;   //after some conditional
  }

  .... //other visit methods

  boolean mustVehicleBeAwarded(){
    return mustBeAwarded;
  }

}

The goal of this design is to allow client to iterate through any collections of Vehicle in order to know which vehicle must to be awarded :

  ...
    VehicleEvaluatorVisitor visitor = new VehicleEvaluatorVisitor ();
    for(Vehicle vehicle : vehicules){
      vehicle.accept(visitor);
      boolean mustToBeAwarded = visitor.mustVehicleBeAwarded();
      .....
  ...

My question is : Is this an acceptable design ? (Of course, Car and award concept is just a theorical example)


Solution

  • It's okay to have a state for a visitor.

    But in most cases it is overcomplicated.

    Consider having a visitor with a generic and your code will turn into:

    Visitor interface

    public interface VehicleVisitor<T> {
        ...
        T visit(Car car);
        ...
    }
    

    With Car class

    public class Car extends Vehicle implements Visitable {
        ...
        <T> T accept(VehicleVisitor<T> visitor){
            return visitor.visit(this);
        }
        ...
    }
    

    And visitor implementation

    public class VehicleEvaluatorVisitor implements VehicleVisitor<Boolean> {
        
        public Boolean visit(Car car){
            ...
            return true;
            ...
        }
        
    }