Monday, January 21, 2008 - On the plane tonight (I'm in Redmond this week) I got to thinking about writing "Maintainable Code" and what it means in light of our fad-centric industry which churns itself every 18 months or so with a new language or platform version. We all inherit projects and are confronted with Geek Lust to rewrite everything in our own image - but what is the motivator for you when you do this? My question to you is: how often do you justify a rewrite (or upgrade) with a platform rev or language change? Good Clients Up until a little over a year ago, I'd had the same client for the close to 9 years: KLA-Tencor. It all started when I wrote a small ASP-classic site for them in 1997 that evolved into a pretty robust Commerce/Fulfillment app in late 2005. You might think this is crazy, but after the initial rev, I rewrote the site 3 times:
Rob, will there be a testing story for the Repositories? That is. how would I go about mocking them out for unit tests so as to avoid hitting the db?It's a good question. My reply wasn't so professional:
@Steve: if you like TDD so much why don't you just marry it :pYou have to understand that I love Steve. No, I LERRRV Steve. In fact I love him so much I stole him from right out of Haack's nose and made him a main committer for the new SubSonic MVC stuff (Steve is Phil's right-hand with SubText). Booya! Anyway - I made sure to follow up the conversation with Steve on Skype to get his ideas, and I asked him what he thought we should do to make some of our new stuff more testable (we have a whole mess of non-virtual, non-interfacable static methods as part of our Data Factory which are not easy to test). He came up with a great plan (paraphrased, geekiness his):
You could crank up an IoC containter and use Dependency Injection...My reply was my usual not-so-professional-smart-assiness:
Ooooh! I like that idea! And look at all the buzzwords I can blog about!I hope you don't read this as me being snarky - I couldn't help myself. Steve is such a good guy and he's shown me some great tricks regarding TDD and tools. But see, when you're nice to me, my claws come out and I rip your best shirt while coughing up stuff on your best shoes. I can't help it... it's my nature. When Do You Tell A Client To Rewrite? So as I sit there tonight on my plane, watching a Horrible Movie with The Rock dressed up as a cheerleader, I got to thinking about Steve and our conversation (Steve used to be in Glee Club and on his highschool Drill Team). Unit Testing is something you learn about in school, but let's face it - no one in the MS space took it seriously until NUnit came out a few years back - it's a "wave" that's hitting it's stride right now (and a very good wave it is) and I'm wondering just how many people will rewrite an old application to be more testable? Even in the case where one might be working just fine? If you were handed an ASP Classic site (yes, there are many) - let's say ... ohhh... Starbucks - would you push them to rewrite it? If so, would a complete set of Unit Tests be part of the cost? A client said to me once (over beers):
It doesn't matter how good the developer tools get, you guys will always find ways to invent work to fill your time and bill me for it.Interesting point and, from a client's perspective, hard to argue with. I didn't tell him I needed Unit Tests 5 years ago - why are they so critical now? Again: I'm not criticizing TDD or Unit Testing. Just using it as an example of something that wasn't commonly done just a few years back. Honestly - please don't flame me :). I love Unit Testing. It loves me too. I think. Anyway... When do you council a client on a rewrite? What sorts of issues come into the conversation in terms of cost/benefit? Have rewrites worked for you and has your client been happy? I'd really appreciate your feedback on this...
In the end I think ROI should be the guiding principle.
In many cases it's a systemic issue. While it's not feasible to sit down and simply start over with an enterprise application, at some point, processes have to be put in place to make sure all new code has a much higher level of quality, maintainability, extensibility - all the "bilities". It's a matter of "stopping the bleeding" before going back and re-writing existing code, and I think TDD is the best way to do this.
Perhaps because I'm a Windows developer, not a "Microsoft" one, I've used unit testing for at least 5 or 6 years solidly. Starting any major project without unit tests just seems strange (and dare I say stupid?). It's not even an extra billable item, it's just "development". They are intrinsically linked in my mind. It's like charging extra if you're going to use a MVC approach vs. WebForms.
As much as I love TDD I'd never rearchitect an application/site just to make it more testable *unless* there were actual issues, such as junior developers that kept breaking things, constant "wonkiness" or just a general uneasiness that "hmm, I wonder if I just broke something". Then you need the tests just as sanity check that things are actually getting fixed vs. playing plug the dam with your finger. That's really what tests are about, not having to worry that you're new fancy QueryExSquared just broke your previous Query98.
I would try to sneak as many tests into a "it's working just fine" system as possible though.
The main theme I'm reading here is that people would rewrite if the cost to expand was too much. Lemme ask another question:
Do you often say that of your own code? If so, what is it in response to? A platform change, mindset change?
How do you justify to your client that the rewrite will "cost" more and in what terms?
Any of my code that is more than a few months old tends to become "Past Shawn's Code", not actually *my* code so I look at it the same way I do someone else's, that is, "I could do it better, who the hell was this guy anyway?" :)
My motivations for wanting to rewrite my own stuff tends to either be that I want to bring it inline with my other projects so it's easier to move between them (like rewriting a classic ASP in ASP.NET only because then everything will be in .NET) or because something has come along that makes the hacks I was attempting previously obsolete, like how I was trying to fake MVC using WebForms or how I used to fake Master pages in 1.1 and then 2.0 offered a "real" way to do it.
Then of course there are those coding epiphanies that totally alter how you view development and everything prior looks like the equivalent of stick figures and you want to obliterate any trace of how you used to do things :)
I try to get the client to make the choice by putting it as plainly as possible in terms of their dollars: I can spend 40 hours a month adding various new features to your website/application or I can spend 160 hours in just *this* month and you'll spend only 2 to 4 hours a month after that. I basically use the same justification with them in terms of money as I do to myself in terms of time and ease. That helps keep me honest as well since sometimes I just want to rewrite the app because it'd be better for me, not them, which is unfair.