OverridableCodeConstants is a configuration design pattern that attempts to blend the advantages of CODE_CONSTANTS with the flexibility of using values loaded from XML configuration files.
It's both traditional and convenient when coding to put literal values into code constants, because:
- Multiple uses of the value can be controlled from one place. (Don't Repeat Yourself principle)
- The value can be given a DESCRIPTIVE_NAME that also distinguishes its role as a constant from variables.
- The value can be a documented public, read-only feature of the class, exposed through metadata, which is helpful to users of the class who might need to pass as a parameter to a method.
But its not convenient when you need to change these constants any more than infrequently, which is why configuration files, registry settings and the like are so universal, because commonly:
- Different release versions of the app need different values
- Different installation of the same release need different values
- Different invocations of the same installation need different values
Static constants are typically assigned when a class is loaded to their value. The OverridableConstants
? pattern checks a backing configuration file at this time, and sets the constant to the value specified by the file, or to a default value otherwise. A Java example:
package model;
class ModelRunner? {
public static final int THREAD_COUNT = Config.getInstance().getInt("model.ModelRunner?.THREAD_COUNT", 1);
What's nice is that:
- It can be done in a single line of code
- The default value is clearly visible
- Finding a collision-free name for the configuration key is trivial using the constants qualified name.
- If we want to get clever we can derive prefix "model.ModelRunner?." automagically from the class.
Some implementation notes:
- I have done this in conjunction with EasyFindMutableConfigFilesInJava and http://jakarta.apache.org/commons/configuration, in such a way that all the features mesh well. Other languages and techs may not work so smoothly.
- The static "Config.getInstance()" may worry people, because it's a naughty static singleton and because so far I've swept the question of how it gets created under the carpet.
- At class load time, when static init code is run, we don't have access to any instances. A static access point is convenient, unlike any alternatives I considered.
- While lazy creation of the configuration is possible in getInstance(), I don't like it because any exception thrown loading the configuration files is given to the client, who cant usefully do anything but fail. I prefer to add a one-shot setInstance() method that code early in startup in responsible for calling. I've used such a pattern over some years with success.
- Config.getInstance() returns a Configuration interface (org.apache in my case), so we aren't committed to a concrete implementation (just that we use the same one everywhere in our system).
- The default Apache configuration XML layout treats "." as a delimiter and maps key names onto a simple nested element structure that intuitive groups together values by package and class:
<config>
<model>
<ModelRunner?>
<THREAD_COUNT>5</THREAD_COUNT>
</ModelRunner?>
</model>
</config>