Это некрасиво, но большинство решений нетривиальных расширений проблемы просто собирается устранить уродство.
Например, вы можете инкапсулировать три различных поведения в трех различных реализациях некоторого интерфейса, а затем передать различные реализации поведения конструктору каждого перечисления. (Это в основном командный или стратегический подход, который предлагают другие).
Если вы сделаете эти реализации и интерфейс отдельными классами, то вы потенциально можете разоблачить это поведение за пределами перечисления, что является ненужным и, возможно, уродливым.
Если вы сделаете их закрытыми статическими внутренними классами перечисления, вы перенесете безобразие из верхней части файла в нижнюю часть файла. Насколько менее уродливо это в глазах смотрящего.
public enum Foo {
ONE(new OneDelegate()),
TWO(new TwoDelegate()),
THREE(new ThreeDelegate());
// ////////////////////
// Private stuff
private final FooDelegate delegate;
private Foo(FooDelegate delegate) {
this.delegate = delegate;
}
// ////////////////////
// Public methods
public String doStuff(String stuff) {
return delegate.doStuff(stuff);
}
// ////////////////////
// Helper classes
private static interface FooDelegate {
String doStuff(String stuff);
}
private static class OneDelegate implements FooDelegate {
@Override
public String doStuff(String stuff) {
return "One " + stuff;
}
}
private static class TwoDelegate implements FooDelegate {
@Override
public String doStuff(String stuff) {
return "Two " + stuff;
}
}
private static class ThreeDelegate implements FooDelegate {
@Override
public String doStuff(String stuff) {
return "Three " + stuff;
}
}
}
Другое очевидное решение состоит в том, чтобы поместить все три поведения в качестве закрытых методов и добавить switch(this)
в открытый метод. Лично я считаю это безобразным грехом, но многим бывшим программистам, похоже, это нравится. :)
public enum Foo {
ONE, TWO, THREE;
// ////////////////////
// Public methods
public String doStuff(String stuff) {
switch(this) {
case ONE:
return doStuffOne(stuff);
case TWO:
return doStuffTwo(stuff);
case THREE:
return doStuffThree(stuff);
// If we're handing all enum cases, we shouldn't need
// a default (and per comments below, if we leave out
// the default, we get the advantage that the compiler
// will catch it if we add a new enum value but forget
// to add the corresponding doStuff() handler
// default:
// throw new IllegalStateException("Who am I?");
}
}
// ////////////////////
// Static helpers
private static String doStuffOne(String stuff) {
return "One " + stuff;
}
private static String doStuffTwo(String stuff) {
return "Two " + stuff;
}
private static String doStuffThree(String stuff) {
return "Three " + stuff;
}
}