Archive

Archive for the ‘Agile’ Category

Technical Debt – how to live with it

March 2, 2010 2 comments

Technical debt occurs in many, if not most software development projects. There are many varieties of technical debt: allowing your software get out of shape, allowing your software to depend on too old third party software and allowing your codebase to gather unreasonable amount of code that is built with bad coding practices.

It can be hard to measure the technical debt or its effect on product development. Individual classes or modules might look pretty much ok. The cumulative effect can be devastating to your velocity especially if the life span of the software is long.

Getting out of shape

Software gets out of shape with every change done to it if you are not observant. Every change is an opportunity to refactor the software for it to be easier to change in future. If you have not done proper amount of refactoring your codebase may get so out of shape that changing or adding features is so slow that it hurts your time-to-market and effort per feature is not competitive.

Constant refactoring is a way of keeping the software in shape. The cost of refactoring in the large (across many classes / modules) might be high if you do not have extensive and fast test harness to test whether the change really works. The temptation to do just the small change for the behavior of the individual method or class that is needed is high.

Refactoring the code might require refactoring many classes so the effort and risk to do that might be higher especially if the code is new to the developer and test coverage is low. Risk of not refactoring increases also when rapid changes to the code are needed due to project deadline pressure or urgent customer problem. Inexperience in development skills or at the particular language & tooling also add to the risk of getting software out of shape. In some cases there might not be proper tools available for refactoring or automating the tests. In those cases some investment on tool development can be beneficial.

Knowledge of code smells (from Martin Fowler’s Refactoring), techniques from Michael Feathers’ book Working with Legacy code and refactoring tools in IDE’s can help. Use of tools like Lattix or Structure101 can help in detecting whether your software is in proper shape. Currently the tools cannot provide a 100% solution even within one language but they are certainly helpful.

Test driven development can be a good practice to use as well but requires strong discipline and can be time consuming if the code base is already legacy. If your code base is already legacy (has little or no tests) the cost of refactoring in the large and TDD needs to be evaluated against business value, not chanted as a mantra.

Allowing your software to depend on (too old) 3rd party software

This chapter mostly relates to product software in large environments because those usually have longer lifespan than small custom projects.

One part of productivity comes from letting others do the work for you – at any time most of the innovation in IT domain is anyway happening outside your company. This means changes that can help you be more productive happen every day/week/month in the form of new versions of especially open source but also commercial software updates.

One of the key enablers for agile development is continuous integration – taking changes in constantly and testing them. You may not want to take third party software in at every patch and release they deliver but you should take them in at sensible intervals. What is a sensible interval: it is a reasoned compromise of the effort and risk of taking a new version and not taking it and having to take it in at awkward timing later. If you delay too long you will find out that this

  • may cause additional work in the form of workarounds
  • may cause incompatibilities of some other software that needs to work in your runtime environment
  • you may lose the productivity benefits of the innovations of this version for the duration of delay (for example: speed, convenience, new features, better abstractions…)
  • you may need to use older tools which are less effective
  • the porting effort might be larger
  • if you are forced to upgrade instead of choosing to upgrade you might block development of features that directly add customer value

This kind of technical debt is easy to accumulate. Advantages of doing the version change can be hard to quantify in business value. Some 3rd party software change so seldom that people might forget that a change might be needed if they are focused only on their current sprint. In addition the effect of living in the current version of the software is affecting most development activities, there might be little understanding what would be the every day benefits of the new version. There might also be bad memories of large effort spent on previous version upgrade.

One should build dependencies to third party software in a sensible fashion so that you can switch to a new version or even completely new library with reasonable effort. One might want to try out the new version parallel with the old one already as soon as it is available. This would also give visibility to benefits. This of course requires that you can afford to have the porting effort to new library done as a spike.

Being able to switch easily to completely new library is a balancing act as too 3rd party independent approach can fail to take advantage of the key attractors of the 3rd party software. One way to handle this could be to define at system level which of the 3rd party software you will not change and which you might. For those that you might want to change run tests with at least two different versions constantly in your continuous integration environment.

I would be interested in other people’s experience in how to detect whether your software is in shape and handling technical debt.

On the next agile category post I will talk more about code level technical debt and static analysis tools.


Categories: Agile, linkedin, Technical debt