IMO, полагаться на позицию, чтобы думать о «следующем» или «предыдущем», было бы плохой идеей, так же как плохой идеей полагаться на ordinal () в коде вашего приложения. Было бы более разумно, чтобы ваше перечисление определяло как вращение должно происходить так, чтобы добавление новых членов между ними не приводило к ошибкам.
Существует два решения, которые вы можете попробовать: убедиться, что каждое созданное перечисление неявно обрабатывает следующее интеллектуально, что обеспечивает большую степень гибкости, или создать общую политику ротации, которая может использоваться всеми перечислениями, которые поддерживают ротацию, но обладают меньшей гибкостью.
Подход 1 (большая гибкость)
enum Direction1 {
EAST() {
@Override
public Direction1 next(Rotation rotation) {
return rotation == Rotation.CLOCKWISE ? SOUTH : NORTH;
}
},
WEST() {
@Override
public Direction1 next(Rotation rotation) {
return rotation == Rotation.CLOCKWISE ? NORTH : SOUTH;
}
},
SOUTH() {
@Override
public Direction1 next(Rotation rotation) {
return rotation == Rotation.CLOCKWISE ? WEST : EAST;
}
},
NORTH() {
@Override
public Direction1 next(Rotation rotation) {
return rotation == Rotation.CLOCKWISE ? EAST : WEST;
}
};
abstract Direction1 next(Rotation rotation);
static enum Rotation {
CLOCKWISE, ANTICLOCKWISE
};
}
Подход 2, более общий, меньше гибкости
interface Rotatable {
// now it would be difficult to make next() method take a rotation
Rotatable next();
}
enum Direction2 implements Rotatable {
// assume clockwise rotation
EAST() {
@Override
public Direction2 next() {
return SOUTH;
}
},
WEST() {
@Override
public Direction2 next() {
return NORTH;
}
},
SOUTH() {
@Override
public Direction2 next() {
return WEST;
}
},
NORTH() {
@Override
public Direction2 next() {
return EAST;
}
};
}