I was late to read: Peter Ahé has a wonderful post on the type of this.
Among the gems:
- Design issues with generics
- A lengthy, well-developed example
- Laird Nelson is a great name
I was late to read: Peter Ahé has a wonderful post on the type of this.
Among the gems:
The Java enum is a nice feature, but like anything it is open to abuse. Witness:
enum OverTheTop {
A, B;
private String value;
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
} Even though the instances of OverTheTop are fixed and immutable, enums are after all simply class instances and can be use anyway a class can be used. This is the same problem with unmodifiable collections having modifiable members.
You could view enums as a generalization of singletons, having a fixed number of members not limited to just one. (Class loading is thread safe — does this mean one can use a single-member enum to implement a thread-safe singleton?)
As abusive as enums with setters seems, worse still remains:
enum TrulyUnpredictable {
A, B;
private Runnable runnable;
public void setRunnable(final Runnable runnable) {
this.runnable = runnable;
}
public void run() {
new Thread(runnable).start();
}
} As unmaintainable as this seems (what does TrulyUnpredictable.A.run() do?), there are legitimate uses for complex enums.
Say you have a limited set of algorithm implementations and would like to switch on them:
enum Algorithm {
FAST(ImplementationFactory.getInstance("FAST")),
ACCURATE(ImplementationFactory.getInstance("ACCURATE")),
EFFICIENT(ImplementationFactory.getInstance("EFFICIENT"));
private final Implementation implementation;
Algorithm(final Implementation implementation) {
this.implementation = implementation;
}
public double calculate() {
return implementation.calculate();
}
} And for the fan of difficult syntax:
enum Algorithm {
FAST() {
public double calculate() {
new FastImplementation().calculate();
}
},
ACCURATE() {
public double calculate() {
new AccurateImplementation().calculate();
}
},
EFFICIENT() {
public double calculate() {
new EfficientImplementation().calculate();
}
};
public abstract double calculate();
} There are very many variations on these themes, but it is not too difficult to reach the point where no one can read your code except you.