April 2, 2011

...Learn TDD with Codemanship

Spring Is In The Air

Yesterday was April 1st - April Fool's Day. Lots of pranks were pulled; not that I would ever stoop to such levels, of course.

And pranks from April Fool's Days of yore also redid the rounds. One that did make me chuckle was this oldie from 2006 (Ah, 2006! Those were the days...) Someone claimed to have created an XML version of C#, demonstrating just how easy it was to write simple code using this new markup language.

The idea of writing C# code in XML is thus shown to be absurd and ridiculous. And yet, these days many of us do something very similar. "Dependency injection" and "inversion of control" frameworks do exactly this. They allow us to express things like object creation, dependency injection and flow of control in XML files.

The usual selling point of these frameworks, like Spring and Castle Windsor, is that they enable us to "soft-code" certain key dependencies to achieve a greater separation of concerns and make our applications easier to change. Some even tout the possibility of allowing non-programmers to edit these configuration files and thus make changes to, say, the flow of the UI without all that fiddly coding, building, testing and redeploying. Hooray for their side!

In reality, it's magic beans (powered by electric parsnips). If you edit an MVC mapping file, you can easily end up with the flow of the UI not matching the state of the user's session. A controller may end up having certain expectations - certain pre-conditions - broken because B didn't follow A as originally envisioned. In MVC, workflows are not infinitely flexible. So it's entirely possible to break an application by editing one of these configuration files. And if it can break it, then editing these files must be followed by retesting of the application. And, in my book, that makes them source code - something only a programmer who knows the system and works with good programming discipline can be trusted to modify.

The consequence of that is simple: when you embed DI or IoC or MVC logic in XML files, all you're really doing is converting C# or Java or Ruby or Visual Basic into the kind of XML representation we'd normally interpret as an April Fool's prank. (Okay, with Visual Basic it might actually be an improvement, but you get the point.)

It's entirely illusory that when you extract a dependency from your code into an XML file that you havr removed that dependency. All it takes is one change to the XML and the effect of that dependency can still be felt in the shape of failing tests and broken functionality, every bit as much as if you'd left it in the code. The dependency is still there, and no separation of concerns has been achieved.

The advantage of leaving dependencies in your Java or C# or Ruby or VB code is that they are easier to see, both by inspection, by the compiler and by static code analysis tools designed to help you manage dependencies.

Heavy reliance on these frameworks will also hit your unit tests where it hurts. They'll run slower and the test set-ups will get more complicated and difficult to manage.

And the funny thing is, I never had any trouble implementing patterms like Model-View-Controller, Dependency Injection or Inversion of Control before these frameworks started appearing. MVC is easy. If you want it really decoupled, try implicit invication (you may know it as the "Observer" pattern). Dependency injection literally just means passing in references to objects, making them more readily substitutible (helps with testability, for example). I mean, c'mon. How hard is it to write a constructor or implement the "Visitor" pattern? As for Inversion of Control; well, that just means that instead of baking in a workflow in the interactions between collaborating objects, we defer to a higher-level object that co-ordinates that workflow from above, making it easier to change and also introducing the possibility of changing the workflow dynamically at run-time.

Since those XML files are in effect source code, I see no real advantages in taking what would have been plain old code written in an elegant programming language with good tool support and translating into crappy markup and sweeping it under the carpet, in the vain hope that what the compiler can't see won't hurt us.

I find it better to have all the dependencies out in the open. It makes managing them so much easier.

Posted 11 years, 5 months ago on April 2, 2011