Re: Visitor pattern vs if-ladder
Lew wrote:
Philipp a ??crit :
I think about replacing an if-ladder (with instanceof calls) in my
code with a visitor pattern, but the advantages are not really obvious
to me.
...
I ran the counting with 8 types of vehicle on 10^8 randomly produced
vehicles 10 times alternatively (each run is ~16 sec, all 20 runs are
in one JVM execution, so warm up should be accounted for). The ladder
implementation is about 10% faster (mean time per run: ladder 16800ms,
visitor 18380).
I'm not saying that this is a big difference or should influence the
decision very much. It's just FYI.
Micro-benchmarks are notoriously unreliable. Aside from that, the real
cost isn't run time but maintainability of the source.
Albert wrote:
For such a simple case, why not using simple overriding ? You could
add a method Vehicle.count(int[]) with one implementation for each
subclass of Vehicle.
This answer points up that a question of the form, "Should I do A or B?"
is often less powerful than, "Is there an alternative to A?" It might
well be that neither A nor B is the best option.
Indeed. Here are a some more options to add to the mix:
1. Use overloading, but make the method merely return an integer
associated with the type. The using code would be:
count[vehicle.getVehicleTypeCode()]++;
The Car implementation might contain:
public int getVehicleTypeCode() {
return 0;
}
2. In my current research application, I need to count things often
enough to have a utility class that just counts:
public class Counter<T>
It uses a Map<T,Count> internally, where Count is a member type that
represents an incrementable integer.
Instead of an array, counts would be a Counter<Class<Vehicle>>, and the
counting code would be:
counts.increment(vehicle.getClass());
3. In general, I don't like tying the logical type of the vehicle so
closely to the implementing class. I can think of cases in which I might
want to have two different implementing classes to represent different
variants on a single logical vehicle, or find that a single class can
implement several logical vehicles conveniently.
For that reason, I might make the logical vehicle type an enum, and use
a Counter<VehicleType> to count instances of each vehicle type.
4. In an additional variant on the enum idea, if I were going to use an
int[] to do the counting, the code would look like:
count[vehicle.getVehicleType().ordinal()]++;
I'm sure there are more ways of doing this. I don't think I know enough
about the real case to have an informed opinion on which I would use.
Patricia