Configuration Source

Dealing with configuration is such a large part of software development, why don't developers don't talk more about it. Is it just too mundane?



Is everyone working in Java so enamored of the Bean style setter pattern? Personally, I think it stinks. The Bean pattern creates a lot of surface area on the class. All those setters often obscure the functional API. A problem that is even worse is the issues related to state transition. Because the setting of the configuration isn't atomic, the object is left in an odd state while the setters are being called. Not good.



One alternative technique I've seen employed is the use of a sibling configuration interface that defines a class’s configuration requirement. Something like:


interface MyConfig {
int getPort();
String getUserName();
double getFraction();
}


This solves the surface area problem and the state issues but it has its own problems. Problems start to creep in with this pattern as you use the object within another object with its own configuration needs. You could have the containing object's configuration object inherit the interfaces of the contained objects but that's an implementation detail better left hidden. That leaves you needing to provide a proxy for your contained objects configuration needs. This is a maintenance problem. Every time your contained object's configuration changes, you need to change your configuration proxy too.



I pondered these issues and can up with a simple solution to deal with configuration in my latest project. I don't know if the pattern has an official name, but I call it 'Key Based Configuration'. The core of it looks like:


/**
* Supply configuration
*/
interface Configurations {
Object get(String key)
}
/**
* Consume configuration
*/
public interface Configurable {
void configure(ConfigurationSource configSource);
}


The very loose coupling between the configuration source and the consumer allows a single configuration instance to be reused between many object. In the most simple case, a system class that manages the overall configuration persistence can just implement the configuration source interface and be passed around.



The pattern is not without flaws, but the following examples show how I deal with some basic problems.

1. The interface is not type safe. Personally, I don't think this is a big issue. I've seen the arguments. Configuration parsing is most often done early and any class cast type exceptions between the producer and consumer will usually show up at startup. If your concern is usability, a simple helper class that adds type semantics can be used to wrap the core configuration source..


public class TypedConfigurationSource {
private ConfigurationSource root;
public TypedConfigurationSource( ConfigurationSource root) {
this.root = root;
}
public String getString(String key)
return root.get(key).toString();
}
public integer getInt(String key)
return Integer.parseInt(root.get(key).toString());
}
etc...
}


2. Namespace issues with reused objects. Sure there can be namespace issues related to multiple instance of the same class with different configuration needs, but these can be handled via a simple namespace wrapper.


public class NamespaceConfigurationSource implements ConfigurationSource {
private String namespace;
private ConfigurationSource root;
public NamespaceConfigurationSource(String namespace, ConfigurationSource root) {
this.namespace = namespace;
this.root = root;
}
public Object get(String key) {
return root.get(namespace + "." + key);
}
}


So far this technique has really worked great. So great in fact I have other thoughts on this topic. But, I will save those for another day.

Comments

Popular posts from this blog

Shark Crackers

Running roughshod or ripshod

Axis, Axes, Axii?