I have several switch statements which test an enum. All enum values must be handled in the switch statements by a case s
This is a variant of the Visitor approach which gives you compile-time help when you add constants:
interface Status {
enum Pending implements Status {
INSTANCE;
@Override
public T accept(Visitor v) {
return v.visit(this);
}
}
enum Progressing implements Status {
INSTANCE;
@Override
public T accept(Visitor v) {
return v.visit(this);
}
}
enum Done implements Status {
INSTANCE;
@Override
public T accept(Visitor v) {
return v.visit(this);
}
}
T accept(Visitor v);
interface Visitor {
T visit(Done done);
T visit(Progressing progressing);
T visit(Pending pending);
}
}
void usage() {
Status s = getRandomStatus();
String userMessage = s.accept(new Status.Visitor() {
@Override
public String visit(Status.Done done) {
return "completed";
}
@Override
public String visit(Status.Progressing progressing) {
return "in progress";
}
@Override
public String visit(Status.Pending pending) {
return "in queue";
}
});
}
Beautiful, eh? I call it the "Rube Goldberg Architecture Solution".
I would normally just use an abstract method, but if you really don't want to add methods to your enum (maybe because you introduce cyclic dependencies), this is a way.