Our firm develops primarily in Java and supports a number of "live" systems (mainly long running server processes), all reliant on shared reference data and enumerations. Occasionally an enum definition expands to include a new value and in this case we currently redeploy all our applications when this happens, the reason being that our applications each have a private "lib" folder containing all library jars (including the "enum entity" library). Obviously this is undesirable and so I'd be interested to hear other people's recommendations or approaches.
Ideas I've thought of:
The problem with these approaches is that applications typically have code in the format:
switch(enumVal) {
case A:
// Do something.
break;
case B:
// Do something.
break;
default:
throw new IllegalArgumentException("Invalid enum value: " + enumVal);
}
... and hence will start failing when they hit the default case. Perhaps this suggests that these entities shouldn't be enums at all; it's really a convenience trade-off in our case. Or perhaps it simply suggests that our apps are too brittle and should handle the default case more gracefully.
Mr. Smith is right: Extending enums, or the old-school "enumeration" int constants for that matter, can hardly be done right and is usually not a good approach.
As you imply, the new enumeration values require a special behavior/handling by clients using them. Once you modify the enumeration, you thus must modify the clients, too. This is really bad and you should really try to re-design it in another way.
Object orientation was invented specifically to solve this problem: your switch is really just an explicit virtual table when an implicit one would have been far better. You should consider redesigning your application to use interfaces/base classes instead of enums.
This moves the problem to object creation time, which gives the immediate advantage of a single change point for each enum. In also opens the way for the introduction of a plugin based architecture which may well not require any recompilation and may even lead to the possibility of extending your application without restarting it. Given that you speak of long running server processes, a reduction in downtime is likely to be appealing.
The easiest way to avoid recompilation is probably to adopt Dependency Injection. With a framework such as Spring you can have one or more configuration files where you specify the objects you need to create and then you can load them by name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With