Tuesday, April 7, 2020

Tech debt considered possibly not harmful

Current wisdom holds that tech debt (poorly-implemented programs or sections of programs) is bad, and should be avoided. Much as been said about "clean code" and keeping the code in a good state of repair at all times. The Agile Development methodology recognizes the need for refactoring, to reduce tech debt.

Everyone agrees that good code is good (for the project and for the company) and bad code is bad (also, for the project and the company).

Except possibly me.

Which is to say, I am not convinced that every project should take steps to avoid or reduce tech debt. I am of the opinion that some projects should avoid or reduce tech debt, and other projects should not.

Which projects should avoid tech debt -- and which projects should allow it -- is an interesting question, and not always easy to answer. But the answers lie within another question: why is tech debt bad?

Tech debt is bad, we all agree (including myself), in that it increases the development cost. The forms that tech debt takes -- poorly written programs, older programming languages or programs that depend on old versions of interpreters or compilers -- slows the development of new features and fixes to existing features. Tech debt also makes for a brittle code base, such that a small change in one section can have large effects throughout the entire system. Thus, even the smallest of changes must be carefully analyzed, carefully designed, carefully implemented, carefully tested, carefully reviewed, and carefully tested again. Each of those "carefully" operations requires time and effort.

But preventing or fixing tech debt also has a cost. It diverts development resources from adding new features into fixing old code. That diversion can delay the implementation of new features (if you keep the size of the development team constant) or increase the cost of the development team (if you add members).

The decision to reduce tech debt depends on one thing, and one thing only: the value that the organization places on the software. And the value of software, while it can be calculated with the rules of accounting for capital expenditures and depreciation, is really dependent on how you use the software.

Any code base can have value from the following uses:
  • Using the application (that is, running it) for company business
  • Taking pieces of the code for use in other applications
  • Copying design of the code for use in other applications (in a different language)
  • Selling the code to another organization
If you are actively using the software (and most likely maintaining it with small fixes and possibly large enhancements), then the effects of tech debt will drive up the development costs, and tech debt should be evaluated and, when reasonable, reduced.

If you are not using the software, but intend to use pieces of the software in other systems, then the cost of tech debt must be discounted. Only the pieces that will be transferred should be considered. The remaining pieces, which will be discarded, have no intrinsic value and you should not fix their tech debt.

A different calculation applies for the transfer of not code but design. Transferring a poor design from one system to another is maintaining a poor design. But it may be more effective to fix the tech debt on the receiving end, rather than in the source system.

If you are selling the code, and this is a one-time event, then I see little incentive to improve the code. Odds are that the purchaser will not evaluate the quality of the code, or provide a higher purchase price for the improved code.

If you sell code often -- and perhaps are in the business of selling code -- then your code is your product, and you should look to remove tech debt from your code. Your code is your offering to your customers, and your reputation is built on it.

The one scenario that I did not list is the decommissioning of software. If your software has a short life (and you must define "short" as it varies from organization to organization) with no use after that life, then any investment will have a limited time for a return. We don't fix cars that are about the be hauled off to the junkyard, and we shouldn't fix software that we are about to discard.

The decision to avoid or reduce tech debt depends on the future use of the software. For some systems, this is easy: long-lived code such as the Linux kernel, or Microsoft Word, or an accounting system, all benefit from reduced tech debt. Other, short-lived code (such as a short script that is discarded at the end of the day) gain little from refactoring and improvements.

The difficult part in this is determining the future of the software. But once you know that, you know how much effort you should put into the removal of tech debt.

No comments: