Clean Code, Ugly Code, Technical Debt and CleanUp Stories
One of the things most Agilists harp on is the need for Clean Code: Code that can be easily extended and maintained, and that Coders shouldn’t be afraid to work with. But, what does this really mean? To answer this question, I turn to some of the best Coders who ever lived:
- ‘Uncle’ Bob Martin: “Code, without tests, is not clean. No matter how elegant it is, no matter how readable and accessible, if it hath not tests, it be unclean.”
- Ron Jeffries: “Clean Code Contains no duplication and expresses all the design ideas that are in the system.”
- ‘Big’ Dave Thomas: “Clean code can be read and enhanced, by a developer other than its original author.”
- Michael Feathers: “Clean code always looks like it was written by someone who cares.”
I could go on and on with these quotes, but I won’t. Let me simply make the following definition: “Clean Code is Code that is Protected by Tests, Well-Structured, and Readable.” I’m not going to differentiate between different kinds of Tests, define what “Well-Structured” means, or try to describe what make Code “Readable.” I’m keeping this simple, and simply saying that, when it comes to Code …
Clean = Protected + Well-Structured + Readable.
UnClean Code is Code that fails any of these three conditions. If it fails all three of these conditions (it is UnProtected, Ill-Structured, and UnReadable), then I call it Ugly Code, and many of you have some Ugly Code sitting around somewhere… just sayin’…
Code that is not Clean is said to have Technical Debt, which is the debt you “owe the Code” to make it Clean — The definitions of Clean Code and Technical Debt are tightly coupled. Sometimes we create new Technical Debt, and sometimes we find existing Technical Debt; in either case, we want to Clean it up as soon as we can… Technical Debt is like a PayDay Loan; if you don’t pay it back real fast it will eat you alive; the interest on the Debt will kill you.
So, what does it take to Clean up Technical Debt? To keep it simple, let’s just consider the case of Ugly Code, which has nothing going for it. In this case, we will need to Protect the Code with Tests and Repair it to make it Readable and improve its Structure. In other words, for Ugly Code,
CleanUp = Protect + Repair.
In general, CleanUp activities can be doing one or both of these things, depending on just how UnClean the Code is. The most common kind of Repair is doing Refactoring, but we can’t Refactor the Code until we have Tests Protecting the Code… the most important thing is those Tests! (Note: I know that many of us — me included — have been using the word “Refactor” as a synonym for “CleanUp” (and vice versa), but it’s wrong and confusing. So, let’s just stop that now, whaddya say…)
So, if you have UnProtected Code, you need to Protect it with (automated) Tests before you do anything else. Unfortunately, Protecting Code with Tests is difficult and expensive, especially if the Code is Ugly. You’ll have to do Exploratory Testing to figure out what the Code is actually doing, and then figure out a way to automate Regression Tests to Protect it. One way to do this is with explicit, Time-Boxed, CleanUp (Protect the Code) Stories in the Backlog, focusing on one Feature at a time.
On the other hand, if you have Protected Code, life is easier. You can simply do incremental Refactoring as part of all your Functional Stories, and clean up the Code a little at a time. But this does require existing automated tests…
So, do you have Clean Code? If not, what are you going to do about your Technical Debt?