Most applications require config of some description and it is considered good practice to wrap any calls which retrieve configured values in a config class and pass that around rather than splattering the codebase with direct calls to the frameworks inbuilt static methods.
With all the applications configs neatly wrapped in one place the code starts to become more maintainable. Yet are we just replacing one evil with another, if somewhat lesser, one? The problem I often see is this Config class finds itself passed from class to class flouting it's promiscuity and leading writers of articles on config objects down paths dangerous and full of inappropriate metaphors more commonly favoured by the ruby crowd.
There is no doubt that it is useful to collate all of the configurable elements together in one (or more) common classes. What should be avoided is leaking this concept through the whole domain and kicking it from object to object like a dirty old data bag which everyone rumages through, unchecked, pulling out stuff on their own whim. Config is an implementation detail which the majority of the application should have no concept of and (like any other such implementation details) it needs to be locked firmly away like a lump of kryptonite in a lead cased layer so it can no longer leak and permeate and weaken your SuperApp.
Let's think about this in a BDD fashion. When your class want's a ghostbusting url who's it gonna call (they have a webpage now dinyuknow)? string Config.GhostBusterUrl? Or perhaps the GhostBusterUrl class? If your class needs a typed collaborator with certain logic and behaviour (even if it is just supplying a valid url) then that's what your class should get. Not some smelly generic config object that dishes out dirty unparsed strings. The tests should be enough to tell you I'm telling you the right thing: several lines of priming the mockConfig are replaced with the simple supply of a GhostbusterUrl.
So how do we get the GhostBusterUrl from a line in config to those poor desperate classes who are being terrorized by spooks? With a little Tell don't ask and a container. Turn the config object inside out, make its role to inject into the application the dependencies it wants to supply. If your config believes it has a GhostBusterUrl then get it to construct one and register it (along with anything else it thinks it might have of use) into the container when the application tells it to. Not only does the config object gain some of its dignity back (some other classes were calling it nasty names, I know, it's the new millennium, but some people still hold the old fashioned ideas) and is safely kept right to the very edges of your application where no one can get at it.
Another positive side effect is that now your config object is giving birth to loads of lovely typed objects that actually do real stuff rather than having wandering hands pluck at its primitives (I know but I did warn it was a dangerous path laden with tasteless innuendos, I was bound to trip). Though of course, be careful not to pollute your codebase with a million classes that simply represent strings and do nothing else (it's a fine line and one you'll need to argue between me, myself and I). It's also one of the easiest refactorings you can do to your code. Give it a go (and if you object on the grounds of their being loads of small types then please find the closet crumbling procedural bridge and throw yourself into the polluted sequential river below).
Thursday, 5 November 2009
Subscribe to:
Posts (Atom)
About Me
- Peter Gillard-Moss
- West Malling, Kent, United Kingdom
- I am a ThoughtWorker and general Memeologist living in the UK. I have worked in IT since 2000 on many projects from public facing websites in media and e-commerce to rich-client banking applications and corporate intranets. I am passionate and committed to making IT a better world.