It is a metaphor commonly understood. Our customers get it. While they may not like it, they do understand. Technical Debt is incurred today and needs to be paid down; preferably sooner rather than later what with compound interest and all that.
Technical Debt is accepted by many as a natural part of the development process. Frankly, I agree. I think Technical Debt is a good thing to take on for short periods of time. Perhaps it is even unavoidable in some cases. Therefor we should expect it and deal with it accordingly.
But there is something insidious going on here. In many cases, perhaps even most cases, what developers are really talking about is code that is not Clean.
And Messy Code is not Technical Debt.
What is Technical Debt?
Ward Cunningham coined the phrase Technical Debt.
"Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object- oriented or otherwise."As he clarifies later in a You-Tube video, Ward was specifically talking about design decisions made in the course of developing software that allowed for more rapid delivery. Rapid delivery not for the sake of meeting a deadline. Rapid delivery to illicit quick feedback, thereby providing the data necessary to adjust the design to be more congruent with actual needs. The object design should change to reflect your current understanding of the domain, even if that understanding is partial. Technical debt is payed back through code refactoring as our understanding of the domain matures.
Ward clearly states, "The ability to pay back debt [...] depends upon you writing code that is clean enough to be able to refactor as you come to understand your problem."
Misunderstandings about Technical Debt
Ward's original description was vague. His clarification which later followed may have come too late. Many had already taken the phrase and added their own flavor to it. Martin Fowler discusses Technical Debt and even refers to Ward's definitions, but then goes on to say "doing things the quick and dirty way sets us up with technical debt". Jeff Atwood also allows the phrase "quick and dirty" to creep into his explanation of Technical Debt. And in an Intel posting, the definition is expanded to:
"Technical Debt is loosely defined as the volume of poorly written lines of code, poorly refactored, not following coding standards, not supported with sufficient unit tests, and the amount of code duplication."This seems to be the common definition of Technical Debt today. And it is most unfortunate.
Messes are not Technical Debt
Poorly written code, lack of standards, lack of tests, code duplication, multiple responsibility, complex interfaces, large classes, poor/insufficient error handling, and opaque intent are all messes. Not a one of them is Technical Debt. And as such, none of them should be categorized as Technical Debt. For a comprehensive listing of messes, see Robert Martin's Clean Code.
Messes Preclude Technical Debt
Technical Debt is paid back through refactoring as our understanding of the domain matures. "The ability to pay back debt [...] depends upon you writing code that is clean enough to be able to refactor as you come to understand your problem."
Clean Code is actually a prerequisite for Technical Debt. If you don't have Clean Code, you cannot expect to pay the debt back. If you have a mess, you cannot reasonably incur Technical Debt. In fact, you are not incurring debt, you are merely adding to the existing mess.
Messes are not Acceptable
Uncle Bob has stated, "There aren't any reasons to make a mess."
I don't entirely agree with Bob on his point. I think there aren't any reasons to leave a mess. TDD encourages us to take tiny steps. Some of these steps result in small messes. Messes that we will clean up in very short order. But we've made a mess nonetheless. And there is no shame in having done so. To leave the mess for any significant period of time or to allow more mess to accumulate is, however, unacceptable.
Stop calling messy code "Technical Debt"
Stop hiding behind the term Technical Debt. If you have messy code, clean it up. Implement the Boy Scout Rule and get it taken care of.
Most important - don't treat the permeation of mess into your system as something natural and acceptable.
17 comments:
Doc,
A former manager of mine agrees with you. He said, "If you do it quick and dirty, then when quick is done all you have it dirty." We don't want to leave dirty code as our legacy for those who come behind.
Also, Smokey the Bear tells us to leave it a little cleaner than when we arrived. I think that is good advice.
Dennis Stevens
http://www.dennisstevens.com
The use of Technical Debt to mean "the debt load of an unconsolidated implementation, object-oriented or otherwise" was around before Ward Popularized it in his '92 paper. (I first heard it used that way in '88 in the context of deferring a compiler upgrade, in much the same way that Ron Jeffries used the phrase in '95 in http://c2.com/cgi/wiki?TechnicalDebt to describe decisions to defer GemStone upgrades.)
If you have a code mess, and the mess is impeding development, what do you gain by arguing that you don't have Technical Debt? Avoidance of stigma?
Dave Smith
Thanks for the feedback. I could not find any attribution to the phrase Technical Debt prior to Ward's use. Attribution to Ward is extremely common - http://en.wikipedia.org/wiki/Technical_debt
That aside, I fear you've missed my point. This is more significant than semantics or stigma.
Technical Debt is an acceptable occurrence in the development cycle. To overload the definition of Technical Debt with items that are actually Messy Code is dangerous. This implies that messy code is a normal and acceptable occurrence in the development cycle. It is not.
The question is where to draw the line. I accept that mess is technical debt, albeit a particularly dangerous form of debt. I think this is what Ward is saying at 4:28 into the video.
"This seems to be the common definition of Technical Debt today. And it is most unfortunate."
If that's the common definition, then it's the definition. Unless we're trying to own the term for a more specific (scientific?) purpose. Otherwise, this is just the old "hacker / cracker" debate.
I think that we're seeing a lot of conceptual confusion because a lot of people in the real world still deal with a lot of messy code. A concept of technical debt that doesn't include "code you wrote when the desire to meet deadline overrode the desire to be correct" isn't as useful in a real-world discussion.
Sometimes an incorrect (from initial usage) generalization of a term isn't a bad generalization.
Of course there's a reason to make messy code: It saves time. That's the entire point of technical debt. It saves time in the present but causes time to be lost in the future. Sometimes, that tradeoff is worth it, other times, it's not.
Well said Mark! I'd like to add, the solution for messy code and technical debt is generally the same: Time to Refactor.
Well said Mark! I'd like to add, the solution for messy code and technical debt is generally the same: Time to Refactor.
Here is a transcript of the video - http://www.c2.com/cgi/wiki?WardExplainsDebtMetaphor
The other reason that messy code happens is because people are learning.
Unless you start with a team of developers born to produce beautiful, clean code, the chances are that someone on that team will be learning. In that respect, messy code _is_ a normal part of the development cycle, as is having it left around.
(Even a team of star devs learnt somewhere!)
So, it's not just about taking the time to refactor - it's about helping people learn. Stigmatising either technical debt or messy code isn't helpful, IMHO - it happens, it will always happen, and having tools and the will to continuously improve is probably more useful than trying to avoid it in the first place.
Of course messy code is technical debt... the association is transparent.
If you write messy code, then release it, you must then go back and fix that messy code, in the simplest form that IS a debt you must repay, therefore is technical debt.
Maybe a useful way to look at it is that Ward is describing responsible debt. Messy, quick and dirty coding is like refinancing your house to take a vacation.
My comment started getting a little long, so I made it a blog post.
It seems to me that the question lurking in the background involves what is left of the concept of technical debt if you exclude "messy" code from it - and what does this concept do for us? If you're not arguing that technical debt should be abolished as nothing more than a euphemism for sloppiness then I would guess that there's a form of "non-ideal" code that is different from "messy" code and is acceptable in certain circumstances. Is this well-written but incomplete code, with omissions clearly indicated by ToDo tags or something similar? Refactorable code versus code requiring a complete rewrite? What do these differences look like? Those are the questions, I think, that this discussion might focus on.
Messy code is just a loan from a loan shark, taken under duress to pay your previous gambling debts.
Ward's Latest input on the topic -
Dirty code is to technical debt as the pawn broker is to financial debt. Don't think you are ever going to get your code back.
http://twitter.com/WardCunningham/status/3742903303
I think poorly written code and duplicate code can be referred to as messy code. And according to the definition, technical debt refers to poorly written code and duplicate code. So I am not convinced with the fact that messy code is not Technical Debt. Also, errors or bugs which get accumulated over time lead to technical debt. These errors or bugs can be said to be caused due to messy code.
Post a Comment