I received an email from my boss with a link to that Spolsky piece on duct tape programmers which had previously got my blood up. The boss obviously doesn’t read my blog, but he’s been around the block enough that he didn’t take Spolsky’s piece at face value.
Nevertheless, when Martin Fowler’s recent post on technical debt came through my reader, I shot the link back to my boss.
Reckless debt may not be inadvertent. A team may know about good design practices, even be capable of practicing them, but decide to go “quick and dirty” because they think they can’t afford the time required to write clean code. I agree with Uncle Bob that this is usually a reckless debt, because people underestimate where the DesignPayoffLine is. The whole point of good design and clean code is to make you go faster - if it didn’t people like Uncle Bob, Kent Beck, and Ward Cunningham wouldn’t be spending time talking about it.
Duct tape design topic (not Fowler’s term, he doesn’t refer to Spolsky’s post at all) is only a quarter of the quadrant in Fowler’s post, the whole post is worth reading.
The inverse to the technical debt metaphor is the investment metaphor, i.e. investing time to build a solid architecture, or refactor, or whatever. This metaphor is widely used, as it’s a natural one. Of course, it potentially runs counter to the YAGNI principle. Interestingly, Martin Fowler is not an uncritical advocate of YAGNI, he expresses his ambivalence in his Is Design Dead piece.
I think it would be worth drawing up a quadrant for YAGNI v. BDUF similar to the one for technical debt. I’m not sure what the axes would be. One would probably be the level of knowledge confidence you have.
“Knowledge confidence” refers to how well you understand your requirements and the technologies and patterns you will use to address them, and the confidence you have that these will not change. In other words, are you sure whether you’re gonna need it, or could it end up being de-scoped to hit a delivery date? What’s the cost of putting in a simpler solution that won’t necessarily address every requirement, then refactoring it as you reach that requirement in the backlog? How does it compare to the cost of developing a more complex solution up front that supports requirements you never get to, meaning there are requirements in between that get left out as well because you spent time on the complexity you didn’t need?