4/02/2009

Properties. And, Java. Lots of languages really, but let's look at Java. Every Java (and other langs too) application of any size is going to be using some properties. Typically, they'll be held in a "myspecializedvalues.properties" file, but not necessarily. For this example, let's assume you are using such a file (and can then thus use Java's built-in property management mechanism), but again, its not really the point. And this approach can be applied no matter what format you choose to store your properties.

The point of this is to show you a better way to manage - a better way to encapsulate and access - your properties so that the implementation is hidden behind an expressive interface, easy for anyone to understand and use.

The point is to show the PropertyFor class, and to tell you why its better than what you probably have in place.

So, this example has a strategy factory class that needs to make its decisions based on a property setting, this property having a true/false (boolean) value. It starts off looking like this:

You'll hopefully notice something about this factory. First, it's primary responsibility is to serve up the correct strategy to its caller. Of course though, you'll also notice that not only does this class do its primary purpose, but it also has a lot of low-level knowledge about how to obtain the information it needs to make its decision. It knows all sorts of things about icky java property mania.

Now, if this is the lone property in your system, than maybe this is okay and doing any kind of extraction here might be YAGNI (you might though, even if that is the case, be bothered by that fact that this class clearly violates the SRP, nonetheless...).

Of course though, this is not the case, and so let's assume that although this is the only class you see in this example there are in fact more properties in your system and more users of them.

So, the logical thing to do is to extract that property reading management into its own class, happy to have its sole responsibility being providing property values. You do so, and end up with this new "Settings" class:

You slap five with your pair and check in, this is much better! Now your factory can do it's job without having any internal worry about where the settings (properties) are really coming from or how they're implemented. Any other users of properties also get the same luxury. A big improvement, no doubt.

Many systems I've seen have figured this much out, and have this in place. A "Settings" class that hides the details of how to look up properties, all you have to give it is the key to the property you want.

But, this has limitations.

First, and as many will figure out and solve on their own, a sprawl of the property key strings hard-coded in the various users of the properties. You want to change this key? Have fun chasing all the uses down. Of course you could create a constants file for these keys, and have the callers only know the constants (which, in Java at least, provides the big benefit of being able to leverage you IDE when you want to change its name), but is that really enough?

Second, yes your factory doesn't know about "ELearningSettings" or the "java...Properties" guts, but it does still have the job of knowing the format of these property values ('Object' in this case) and how to turn that into what it really wants, a boolean.

Third, particularly if haven't created a constants file (in response to the first problem), how easy is it for future developers to go to one place and see all the possible properties/settings the system has available for them?

There may be more limitations, but that's enough for me.

So, our answer to each of these questions is where the magic happens, the MBark of this article. We evolve our generic "Settings" class into a domain-friendly "PropertyFor" class:

What did we do here? Well, we've taken all the knowledge highlighted above as our limitations and removed it from our factory (really, from all of the users of settings), and put it into our "Settings" class - which, as a result, now becomes a more useful, expressive PropertyFor utility.

So, you'll see our factory now has to worry just about choosing a strategy, and no longer has any overhead related to obtaining the values it needs to make its decision. More specifically, it doesn't know where the settings come from, doesn't know the details of how to access them or the keys that identify them, and it doesn't know what raw format they come in. The factory knows it needs the boolean value of whether or not to "ignore code", and it gets that in one clear, simple line of code.

Further, you've got the beauty of expressive methods on singular class to be very domain-centric in assisting other programmers to access the available setttings/properties for your system - these methods, not only being clearly and expressively named, but also being typed appropriately for ultimate ease to the consumer. And of course, when you need to change the name of the setting and/or the name the callers know it by, no problemo.

So, that's really the main meat.

For good measure though, we take a moment to improve the design of our PropertyFor class. First, this isn't the only boolean setting we have (use your imagination) so we should have a nice clear reusable method to handle our boolean typed settings:

Subscribe To

Prior Art

About MB

I dig bringing great things into the world, and sharing with other people. I've been doing various forms of bad-ass software for years, and these days I work for Industrial Logic as an XP coach/trainer, as well as write weekly for InfoQ. Frankly, I love doing this stuff, and love helping others love it too.
Twitter @ mbria