mechanicalSPIRIT

B.T. Franklin's blog

« Back to blog

Java Programming Tip: Lost in DEFINED_VALUES - Datatypes vs. Constants

There are plenty of situations where you need to identify a few particular "types" of something in your code. For example, maybe you have three kinds of files: User Files, Administrator Files, and Log Files. Generally, the first solution I've seen people employ is to immediately start defining constants somewhere: USER_FILE, ADMIN_FILE, LOG_FILE. You probably know what I'm talking about. Chances are you've even done it. I know I have! Particularly before the introduction of typesafe enums in Java 5, this use of constants was commonplace.

It's a bad idea. The reason why may not be obvious, but let me tell you a story and perhaps it will become clear.

I was once asked to write an event bus to synchronize an application's internal state. I've posted previously about how to properly build an event bus, but at the time it was my first attempt to do so, and I really had no idea what I was doing. I began by writing a big interface file that contained all of the types of events you could possibly fire, defined with Strings associated. You know, stuff like this:

final String COMPONENT_CHANGED_EVENT = "ComponentChanged";

final String MOUSE_PRESSED_EVENT = "MousePressed";

Of course, beyond that, each event could have various specific variables associated with it:

final String COMPONENT_CHANGED_EVENT_COMPONENT_TYPE = "ComponentType";

final String MOUSE_PRESSED_EVENT_BUTTON_ID = "ButtonID";

final String MOUSE_PRESSED_EVENT_TIMESTAMP = "Timestamp";

You get the idea. There were only a handful of events to begin with, so it seemed like a reasonable solution at the time, and had the added benefit (I assumed) of linking the event types to nice human readable names that you could print out if you wanted to.

As you might imagine, the application continued to grow. New event types were introduced, and with them came new variables. Soon the interface file was screen after screen of inscrutable definitions. Worse yet, identifying the type of event in the code that was receiving the events amounted to gigantic switch statements checking for specific entries out of this interface file. It was a bad scene. I wished I could undo it. In fact, I still wish that today. I hope the coders who came after me replaced every bit of it with something more sensible!

So what should I have done instead? I should have utilized the Java language properly, leveraging its strong awareness of datatype, rather than trying to essentially redefine the concept of datatype on my own. I should have extended a common "Event" datatype, and then extended those subtypes further. Beyond simplifying the process of detecting and filtering event types, this would have allowed me to group variable definitions with their specific associated event datatype by putting them inside its definition, rather than by trying to "match the names" in a single huge file.

As misguided as my strategy was, it's not that uncommon, sadly. Most developers don't take it to the same extent, but I've seen it to varying degrees, and it's always ugly. So, if you find yourself trying to identify the "type" of anything by using static final fields or anything similar, stop and think for a moment. Investigate using typesafe enums. Investigate using true datatypes. Down the road you'll thank yourself for it (and maybe you'll remember to thank me, too)!

Posted May 12, 2010