Wednesday, May 30, 2007

Retro-fitting design, unit tests and coverage

Blog is back in business, after a good run of dormancy. Or is it? We'll see.

A while back, I got caught up in the hype surrounding test driven development. I read a bit about it, and while the whole Agile religion got to be a little too much for my tastes, I've tried to adopt a few of the practices. Of course, I see the point of writing the test first since it would be easy to get a unit test for an existing piece of code to verify that it does what it does. However, when you're aware of this, I've found that it forces you to put more thought into how you implement the test for existing code, which in turn can open your eyes to some good refactoring opportunities.

However, some other parts of the mantra (like pair-programming and their seemingly obsessive attitude about snacks) are simply not for me; It's hard to work in pairs when you're alone, and snacks might be the best way to treat my newly discovered diabetes. Well, I guess I can eat some fruit.

However, I can easily see the benefits of Test Driven Developement and refactoring, even in a relatively simple desktop gadget like Sloth. Keep in mind that I've been learning .NET and C# along the way here; Object oriented programming is something that has been completely new to me until recently. I guess you could say I'm the worst kind of self-taught waterfall-cowboy. :)

So, what happens when you mix a little theory on OOD, refactoring and unit testing with the spaghetti code from hell that is your existing project?

Well, at first I was very happy that these new ways of thinking helped me do a lot of clever refactoring. Code was optimized (no, not performance optimized), moved around, things are only done once, in smaller units.. The libraries have become leaner and more maintainable. That's for sure.

Then came the time for getting rid of some serious code smells. Almost all of the configuration related code has been moved to the designated library - except for the ancient configuration window, where a LOT of nasty code duplication is happening, and the main Session object, a textbook example of a God object if I ever saw one.

One of the problems with the fact that I was trying to apply the proper Object Oriented Design after the fact, is that the configuration window had no concept of the SlothConfiguration object. This object (via it's subobjects) contains everything you need in a configuration, and both the Wizard and Sloth itself uses it for everything config-related. Except the config window. It just copies out the bits and pieces it likes, and then leaves the session object to figure out what to do with a zillion properties. Apart from the maintenance horror, there are just so many things wrong with this that the few hairs I have left turn gray just looking at the code.

So after two weeks of boring code-monkey grunt work, I am almost to the point where I can start testing again; The configuration window knows nothing of the underlying logic, it just clones itself a config object and uses it. Then, if the user is happy and closes with the OK button, this config is made active. Sounds simple, right? Well, NOW it is.

So what I have left now is a God-object (10% smaller than when I started) that still needs heavy refactoring, a relatively flexible config solution, and utility libraries that keep growing. What's next?

Well, for a desktop application like this, the cool thing is of course adding new features. And I will do that. However I will spend half the coding time refactoring and testing until I can show the Sloth source code to someone's grandmother and not be embarassed. That'll take a while.

I must add that the process of learning to utilize unit testing (a process which I am nowhere near mastering) has been quite painless thanks to three very nice projects: TestDriven .NET, MbUnit and NCover. I love using them, and can recommend them to anyone wanting to give unit testing/test driven developement in Visual Studio a try.

All right, that was my first attempt at a blog rant. I already see that this was pretty boring, so if anyone by chance stumbles on to this blog, thanks, I'm not expecting to see you again. :)

No comments: