I am adding this as a second answer rather than updating my existing answer as I think that it is too different to the answer that people have already upvoted.
An alternative to holding the options inside the class is to define mappings externally. This might be a better option if you want to be able to support more than two mappings.
The advantage of this is that you can define new mappings which are private to specific bits of your code: there is no need to change the definition of the enum when you add a new use case.
For example:
EnumMap<Foo, String> numberEnumMapping = new EnumMap<>(Foo.class);
numberEnumMapping.put(Foo.BAR1, "1");
numberEnumMapping.put(Foo.BAR2, "2");
numberEnumMapping.put(Foo.BAR3, "3");
Map<Foo, String> numberMapping = Collections.unmodifiableMap(numberEnumMapping);
EnumMap<Foo, String> letterEnumMapping = new EnumMap<>(Foo.class);
letterEnumMapping.put(Foo.BAR1, "x");
letterEnumMapping.put(Foo.BAR2, "y");
letterEnumMapping.put(Foo.BAR3, "z");
Map<Foo, String> letterMapping = Collections.unmodifiableMap(letterEnumMapping);
// ... More mappings.
(I'd personally use a Guava ImmutableMap for this, but you might not want to use Guava).
You can then pass around the Map<Foo, String> to the place where you need to perform the mapping:
void doSomething(Foo value, Map<Foo, String> mapping) {
System.out.println(mapping.get(value));
}
You could define an interface rather than using the Map, if you think that is neater:
interface FooStrategy {
String get(Foo value);
}
but the idea is the same: pass the FooStrategy to the place where you need to turn a Foo into a String.
void doSomething(Foo value, FooStrategy mapping) {
System.out.println(mapping.get(value));
}