Pure Danger Tech


navigation
home

Defining application properties with an Enum

10 Jan 2008

I’ve been playing this week with defining an application’s properties in an Enum and so far it feels pretty nice. I’m sure people smarter than I have already done this but it’s the first time it occurred to me. The topic of app configuration is itself a topic I have many thoughts on…but that’s another post.

The basic idea is that I have some properties that configure my application and I have property keys that indicate how to retrieve those values. Rather than create a file of constants (maybe the best case) or worse just litter my code with constants in many places (the common case in my experience), I define in an Enum all of the properties, their default values, and other information.

Here’s a starting point:

[source:java]

public enum AppProperty {

FOO(“app.foo”), // no default

BAR(“app.soup”, “false”); // no soup for you

// enum state doesn’t have to be final…but doing otherwise

// is almost always a bad idea – don’t do it!

private final String propertyKey;

private final String defaultValue;

private AppProperty(String propertyKey) {

this(propertyKey, null);

}

private AppProperty(String propertyKey, String defaultValue) {

this.propertyKey = propertyKey;

this.defaultValue = defaultValue;

}

public String getPropertyKey() {

return this.propertyKey;

}

public String getDefaultValue() {

return this.defaultValue;

}

public String computeValue(Properties props) {

return props.getProperty(getPropertyKey(), getDefaultValue());

}

}

[/source]

So, here we define an enumerated type with 2 values – FOO and SOUP, each of which represent a property that can be passed to my app for configuration. FOO has no default value and SOUP has a default of “false”. The property key to use is always defined in exactly one place – in this enumerated type. You can get it by simply saying AppProperty.FOO.getPropertyKey().

You can use the computeValue() method to compute a value from a Properties source and the default value for the property. For example: AppProperty.FOO.computeValue(System.getProperties()).

A nice fallout from using enum is that you can get an enumerated list of all app properties. If you happened to also store a property description in here, you could actually build a generic usage method that walked all app properties (order defined by order of the constant definition) and printed the key, default, and description.

Or you could add type information here for common property types (boolean, int, date, etc) and methods to help you retrieve a type-specific value (auto-convert to Integer, Date, Boolean, etc).

It would be great if this could be made generic, but it’s not possible to create abstract enums, which would let you define everything BUT the constants and then subclass to set the constants. Fred Simon has proposed something like this for Java 7 and even built a patch to try it.