Questioning Technical Debt

Technical debt is a metaphor that lets developers explain the need for refactorings and communicate technical trade-offs to business people.[9] When we take on technical debt we choose to release our software faster but at the expense of future costs, as technical debt affects our ability to evolve a software system. Just like its financial counterpart, technical debt incurs interest payments.

Technical-debt decisions apply both at the micro level, where we may choose to hack in a new feature with the use of complex conditional logic, and at the macro level when we make architectural trade-offs to get the system through yet another release. In this sense technical debt is a strategic business decision rather than a technical one.

Recently the technical debt metaphor has been extended to include reckless debt.[10] Reckless debt arises when our code violates basic design principles without even a short-term payoff. The amount of reckless debt in our codebase limits our ability to take on intentional debt and thus restricts our future options.[11]

In retrospect it’s hard to distinguish between deliberate technical debt and reckless debt. Priorities change, projects rotate staff, and as time passes an organization may no longer possess the knowledge of why a particular decision was made. Yet it’s important to uncover the root cause of problematic code since it gives you—as an organization—important feedback. For example, lots of reckless debt indicates the need for training and improved practices.

That said, this book uses both kinds of debt interchangeably. Sure, technical debt in its original sense is a deliberate trade-off whereas reckless debt doesn’t offer any short-term gains. However, the resulting context is the same: we face code that isn’t up to par and we need to do something about it. So our definition of technical debt is code that’s more expensive to maintain than it should be. That is, we pay an interest rate on it.

Keep a Decision Log

images/aside-icons/tip.png

Human memory is fragile and cognitive biases are real, so a project decision log will be a tremendous help in keeping track of your rationale for accepting technical debt. Jotting down decisions on a wiki or shared document helps you maintain knowledge over time.

Technical debt is also frequently misused to describe legacy code. In fact, the two terms are often used interchangeably to describe code that

  1. lacks quality, and

  2. we didn’t write ourselves.

Michael Feathers, in his groundbreaking book Working Effectively with Legacy Code [Fea04], describes legacy code as code without tests. Technical debt, on the other hand, often occurs in the very test code intended to raise the quality of the overall system! You get plenty of opportunities to see that for yourself in the case studies throughout this book.

In addition, legacy code is an undesirable after-the-fact state, whereas technical debt may be a strategic choice. “Let’s design a legacy system,” said absolutely no one ever. Fortunately, the practical techniques you’ll learn in this book work equally well to address both legacy code and technical debt. With that distinction covered, let’s look into interest rate on code.

Interest Rate Is a Function of Time

Let’s do a small thought experiment. Have a look at the following code snippet. What do you think of the quality of that code? Is it a solution you’d accept in a code review?

 void​ ​displayProgressTask​() {
 for​ (​int​ i = 1; i < 6 ; i++) {
 switch​ (i) {
 case​ 1:
  setMark(​"<step 1"​);
  updateDisplay();
 break​;
 case​ 2:
  setMark(​"<step 2"​);
  updateDisplay();
 break​;
 case​ 3:
  setMark(​"<step 3"​);
  updateDisplay();
 break​;
 case​ 4:
  setMark(​"<step 4"​);
  updateDisplay();
 break​;
 case​ 5:
  setMark(​"<step 5"​);
  updateDisplay();
 break​;
  }
  }
 }

Of course not! We’d never write code like this ourselves. Never ever. Not only is the code the epitome of repetitive copy-paste; its accidental complexity obscures the method’s responsibility. It’s simply bad code. But is it a problem? Is it technical debt? Without more context we can’t tell. Just because some code is bad doesn’t mean it’s technical debt. It’s not technical debt unless we have to pay interest on it, and interest rate is a function of time.

This means we would need a time dimension on top of our code to reason about interest rate. We’d need to know how often we actually have to modify (and read) each piece of code to separate the debt that matters for our ability to maintain the system from code that may be subpar but doesn’t impact us much.

You’ll soon learn how you get that time dimension of code. Before we go there, let’s consider large-scale systems to see why the distinction between actual technical debt and code that’s just substandard matters.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.175.7