Messy Code is not Technical Debt

Technical Debt is a common topic these days. How is it incurred? How should we track it? When should we pay it down?

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 elicit 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.

Create a Culture of Integrity

My friend Patrick Wilson-Welsh once asked me if I knew the key distinction between Accountability and Integrity. I said I did, but then found myself struggling for an answer.

Today, I think I get it. Perhaps I should check with Patrick.

Accountability and Integrity

Accountability

Accountability is enforced externally; it is a requirement or expectation to justify actions and decisions. A person can be accountable to or accountable for, but cannot be simply accountable. Accountability requires another party.

Integrity

Integrity is enforced from within; it is a quality of honesty and morality. It exists regardless of accountability. A person has integrity (or does not). Integrity does not require another party.

A key difference

Accountability is flawed. There are numerous issues, from the "it's not wrong if I don't get caught" mentality to the "that is how the boss wants it done" escape clause. Accountability can be unreliable. If expectations are not clear, if the boss is away, if people feel dis-empowered (which is likely), or if people "suck up" to the boss, the outcome may not be what is desired or expected. As a result, morale can deteriorate and lead to more issues. Ultimately, accountability of subordinate to superior creates an environment of distrust and dysfunction; this cannot scale.

Integrity does not require external enforcement. Integrity does not have escape clauses. Integrity is consistent. Integrity cannot be "sucked up" to. Integrity is reliable. And integrity scales.

Some will argue that integrity is adherence to a moral and ethical standard, but is independent of the nature of that standard. This is true. Integrity in not synonymous with morality, rather it is one's ability to be true to their own morality. This makes integrity no less desirable.

Creating a culture of integrity

So how do we create a culture of integrity?

Have integrity

Leadership sets the tone. Hypocrisy will not beget integrity. If you make promises, but don't keep them; If you expect full disclosure, but hold back data; If you promote autonomy, but punish "mistakes"; If you preach teamwork, but practice espionage; you had best expect to be surrounded by people adept at surviving in such an environment.

Hire better

It is quite likely you are hiring based on the wrong criterion. Typically, candidates are first filtered based on credentials and experience. Do they have the requisite degree/certification? Have they used our target tools for the requisite length of time? Then, they are interviewed to certify the proclaimed credentials and experience. Finally, in more progressive environments, the preferred candidate meets the team to make sure there is good chemistry; a quick check to ensure nobody resorts to fisticuffs.

Invert the selection process. Don't hire based on experience and credentials. Hire based on aptitude and attitude. Aptitude - can they learn what you need them to know? Attitude - are they a fit for your team and your company? Put the time and effort into making sure the candidate is capable of learning, willing to learn, and has values that fit for your organization. If they have the pedigree too - Hey, that's swell.

Why invert the process? Smart people easily learn new skills. Selfish people don't easily develop empathy.

Communicate expectations

Produce a values statement. Publish it. Share it. Use it in the selection process.

Develop a code of conduct. What is expected of employees in and out of work? Keep it general. Trust your employees to apply the guidelines rather than providing a tome of situational requirements.

Model specific behavior

We've covered that you should have integrity, which is paramount. Modeling the specifically desired behaviors reinforces the expectations and encourages voluntary adherence. If team members perceive a lack of integrity in leadership or among their peers, they are less likely to exhibit integrity themselves. This is not to say they will lack integrity, but they may not openly show it. An environment of deception encourages the righteous to be cautious.


Integrity Endures

Accountability works, but it is ultimately the coercion of good behavior through fear of repercussion, no matter how gentle. If you want success that endures; create a culture of integrity.

Keep Retrospectives Fresh

Retrospectives are an important (and frequently poorly done) practice. They provide an opportunity for discussion, learning, and adaptation. Without retrospectives, a team is likely to fall into a soothing rhythm and fail to recognize early the need for change.

But retrospectives themselves can become common and numbing. The same moderator, the same three questions, in the same room, at the same time .... (yawn).

Here are a few tips on keeping your retrospectives fresh.

Change Venues and Schedule
Hold iterations in different rooms. Move them to the afternoon before or the morning after their regularly scheduled time. You'll get a different energy and perhaps a different perspective.

Change Moderators
Not only can changing the moderator change the pace and style of the discussion, but it can change the way people communicate. Allow each team member who is interested the opportunity to moderate retrospectives.

Change Styles
We're all familiar with the standard three-question, moderator as scribe format for retrospectives. Mix it up. Use the starfish or circle of questions. Have people write their own suggestions on index cards, have a third-party collect them and write them on the board. Find new ways of soliciting input and you will get new input.

Change Focus
Hold retrospectives with a broader focus. Rather than discussing the last iteration and the next iteration, discuss the last several weeks or months and the next few months. Allow the team to not only discuss the tactical, but the strategic. With a new focus comes new perspective and new insight.

Retrospectives are about learning and adapting. They are critical to the long-term success of an Agile team. If you're not doing them; start now. If you are, make sure you keep them fresh to get maximum value from them.