The primary problem with dirty code is that it adds a cognitive tax to the code base - anybody coming to the code base is going to have to invest considerably more effort attempting to unravel the mess than the problem at hand actually demands.
The more dirty code grows, the worse it gets, sometimes to the extent that the code base becomes so messy that certain features become prohibitively costly, and the road back is long and arduous.
Maintaining clean code (which basically implies constant refactoring) is a lot like brushing your teeth - seems like a hassle at the time, but if you don't do it you're pretty well irreversibly fucked in the long term.
Also on this subject - the 'Big Ball of Mud' architecture [anti-]pattern - http://www.laputan.org/mud/
I've found quite the opposite. The dirtier the code is, the more you try to keep the same guy on it. You hesitate to commit him to any other projects if there's even a prospect of needing him to work on "his" code. Programmers love that shit, especially the ones who write dirty code. It makes them feel smart, important, and indispensable (which unfortunately they are.) Plus, nobody is going to be looking over their shoulder gasping and saying "no wonder it's always broken!" because nobody else wants to get their brain dirty in that code. If you're a bad coder, taking ownership of your own crappy applications is your ticket to escaping peer review and protecting your job.
By contrast, the most vital and hard-core piece of C++ code we have at my company has had contributions from almost half the C++ developers we've employed, thanks to a great initial design and good stewardship. It's nobody's code except whoever is currently hacking on it. That doesn't inhibit people from feeling responsible; the quality of the code inspires everyone to maintain it even though nobody has any real claim to ownership.
1) Dirty code has "concepts that don't map to the domain". This is true at one level of abstraction. An Orbitz-like application is going to have objects representing flights and rental cars and hotel rooms. But a couple of levels down, there are highly non-intuitive search algorithms with all sorts of concepts that have no obvious connection to the domain. I think the real point is not to expose low-level abstractions higher up.
2) "Dirty code inhibits the formation of an ownership culture". A huge problem with dirty code is that it is permanently owned by the author. No one else can possibly fix or extend it. What you really want is code so transparent that anyone can get into it quickly and easily.
In my experience, most dirty code isn't really owned by anyone. Person X wrote a widget, then something changed elsewhere to make it obsolete, but there wasn't time to rewrite it to properly reflect the new situation, so instead Person Y added some quick workarounds. Now neither X nor Y fully understands the widget any more. (Y might equal X - it's hard for a good programmer to feel ownership for a rush job they know to be suboptimal.)
Later, there's a codebase-wide optimisation drive, driven by person Z. Z asks who owns the widget, both X and Y shrug, so Z skims through the code, comes to his own incomplete understanding, and duct tapes over the patches from the previous rush job.
In this way the widget becomes a no-man's-land, where everyone goes to add a quick hack, but nobody wants to take enough responsibility for to nuke it from orbit.
But I can see how a series of owners can produce the same situation.
2) Regarding ownership culture - that's exactly what I meant. If code is clean, anyone is comfortable touching it. If it's dirty, people start going directly to its author. Clean code is an organizational lubricant.
There always are. I took it to mean that dirty code has concepts that don't map properly to the domain, i.e.:
1) Objects that claim to map to the domain, but do so badly, or do so partly but fail at this in obvious and subtle ways.
2) Leaky abstractions
A huge problem with dirty code is that it is permanently owned by the author
Or worse, nobody will go near it. Coders move on or forget the hack that they did in the crunch, so the author may be absent or disavow it. As commented elsewhere, he meant to say "Dirty code inhibits the formation of a good, collective ownership culture"
If the original title begins with a number or number + gratuitous adjective, we'd appreciate it if you'd crop it. E.g. translate "10 Ways To Do X" to "How To Do X," and "14 Amazing Ys" to "Ys." Exception: when the number is meaningful, e.g. "The 5 Platonic Solids."
The story of IMVU is (I think) even more fascinating. I see your ads all over the place (and therefore assume you're successful) but it really is a case of "who the hell knew THAT would be successful. I mean - IRC with 3D avatars? Brilliant! :) (I oversimplify out of ignorance, not disrespect. I've never used the service, but assume it's very much loved by the target market).
Test Driven Development and even just writing unit tests is so much less rewarding, because you can't say "see? look, I've made something new" - in fact - 99+% of the time, they're really just about proving 1+1=2. Who gets excited by writing a test to tell you that the sky is up and apples fall down?
It's only a few thousand lines of code in that that kind of validation and reassurance really starts to pay off. Once you get yourself that far into the matrix - you really need someone to tell you which way gravity falls.
(Should I have gone with an inception reference instead? blah blah falling top)
This is very true, and it's also true that clean code can turn into a core competency in itself. The company I work for got a big competitive advantage by being the best at something that at first seemed tangential to our core competency. We added some features, kept them clean, found it easy to add more, and eventually we had another "core competency" that we never even planned. We had no strategic plan or strategic commitment of resources to develop our capabilities in that area; it only happened because it was so easy to add the features our customers asked for, because the code was clean. (We were also lucky that our early customers asked for the right things, which resulted in us having an attractive suite of features.)
This seems to have been written around the same time (Oct 2008) as IMVU started talking about the benefits of continuous deployment (Feb 2009 http://timothyfitz.wordpress.com/2009/02/10/continuous-deplo...). I'd be interested to know whether their CD-based development strategy helped to dig them out of the hole they apparently coded themselves into.
I'm Chad, the author of the post in question.
IMVU had been doing continuous deployment since I joined in 2005. We even forced daily mandatory upgrades to our client! Luckily our early adopters forgave us back then... We followed a simple algorithm: ship it, and if it sticks, work on it more. If anything regresses, write a test.
This left us with a "bag of parts" product and a lack of technical vision. We've been paying for that since. On the other hand, we've managed to double the business year on year while slowly improving the code, so it's hard to complain too much. ;)
While I am still a huge proponent of test-driven development and automated tests in general, I now see that a coherent technical design is more valuable. Instead of investing heavily in end-to-end tests, we should have mercilessly refactored the code to reflect the product, at the cost of short-term regressions.
I hope that answers your question,
So in your opinion, has continuous deployment actually made it harder to do the kind of proactive refactoring you describe? Or do you just mean that in an ideal world you would have done both from day one?
Not looking to stir a flamewar - I just found Timothy's posts on continuous deployment quite inspirational, so I'm very interested to hear more viewpoints on how well it works.
I actually think that continuous deployment makes it significantly easier to do proactive refactoring. One of our favorite things to do at IMVU is to refactor lots of code and see what breaks in the thousands of tests we run before deploying.
It's true that this sometimes exposes deficiencies in our test coverage, but most of the time, our massive build cluster does a great job of sussing out any of the unknown dependencies that might have broken as a result of refactoring. I, for one, would be more afraid to go back and fix an ugly system if I didn't have the safety net of the continuous deployment process, because it makes it so that I don't have to necessarily have the whole system in my head before starting. I would never make huge changes if I had to live with that fear.
I think Chad is right, though -- it's certainly better if something has a coherent technical design up-front, because when you go to read the code and understand they system, it just makes sense. You don't end up with as many landmines that require tons of refactoring to be able to iterate on them.