Tag Archives: Technical debt

The phrase “technical debt” has become a commonly used phrase in software development. Technical debt was introduced by Ward Cunningham to describe the cumulative consequences of corners being cut throughout a software project’s design and development.

Imagine you need to add a feature/functionality to your software. You see two ways of doing it, the short & quick & dirty one that will make further changes harder or the clean way that will take longer to add.

Technical debit is analogous to financial debt; the technical debt incurs interest payments which come in the form of extra effort you have to do in the future because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design.

“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… 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.” (Ward Cunningham, 1992)

Technical debt trends to accumulate over time

The time you spend below the line takes away from the time you are able to spend above the line in terms of delivering new value to the customers.

Impacts of Technical Debt

Too much time maintaining existing systems, not enough time to add value – fixing defects or n * patching the existing code.

Takes more effort (time & money) to add new functionality – you are not able to react to what’s happening on the market in terms of competitive products.

User dissatisfaction – usually the functionality you’re adding is not what they expect or they struggle with the products due the amount of defects.

Latent defects – a defect that is not known to the customer unless he faces an unforeseen situation but at the same time the developer or the seller is aware of the defect.

Consequences:

Innovator’s Dilemma– once dominant in the market, your competition can develop and deliver new functionality faster than you

studies reveal that every 1$ of competitive advantage gained by cutting quality / taking shortcuts, it costs 4 x times to restore the quality back to the product

The biggest consequence – it slows your ability to deliver future features, thus handing you an opportunity cost for lost revenue

The “source” of Technical Debt

Technical debt is comes from work that is not really Done or steps skipped in order to get the product out of the door (schedule pressure).

A “valuable” source of “undone” work is generated by not knowing what’s required and we add code that performs functionality that’s incorrect. In this scenario we potentially try to tweak the functionality with workarounds by doing some “code manipulation”.

It is important to take sprint capacity and perform the above steps every single sprint.

Paying Off Technical Debt

Stop creating new debt

Make a small payment regularly (eg. each sprint)

Repeat step 2 🙂

1.Stop creating new debt

Clearly define what “DONE” work is!

Know “what” the functionality is – clear acceptance criteria

Automated testing

repeatable, fast – do it every time the code changes!

regression tests – at least every sprint to be able to run through all your regression tests and know that whatever used to work still works.

new functionalities – automatically testing so that can be very clear not only works when it’s new but next sprint when we’re modifying things around functionality, it’s still working as expected.

Refactor – not rewriting the application/product but increasing the maintainability of the code without changing the behavior. It can be changes to make code readable/understandable (variable/methods name change to match the true meaning), taking our redundant code and creating a method. Fixing defects is different to refactoring. Refactoring is best done very small steps, a little bit at a time and actually requires automatic testing to make sure that the refactor has not changed the behavior. See Martin Fowler – Refactoring – Improving the design of existing code

Note: Those are some examples and not an exhaustive list of things that can generate technical debt.

2. Pay off existing debt

Fix defects – preferable as soon as you find them. Get them at the top of the list, work them off (zero bug policy), get them out of the code, refactor the code, improve the structure, make the names meaningful, reduce complexity, remove duplicate code, improve the test coverage.

Test coverage – it doesn’t mean only lines of code, it means testing though the logical use of the code. Test coverage is expensive so it’s most important to test the product with actually being used – the coverage we care about most because it’s how customers are using our software.

The goal: to pay the tech debt a little bit at a time every single sprint and avoid “technical bankruptcy”!