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)
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 you 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;
        ...
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With