Code Life Cycle: Every Line is Technical Debt
Programming in teams is hard: members favour their own code; ownership is important; once committed, code is hard to remove. Training new members is hard: they may not have confidence in their contributions; senior members my protect “their” work; all are afraid of pollution. It is desirable, but usually not practical, to have the following:
- Freedom to experiment and make mistakes while learning, improving and contributing to production.
- Easily learnt and maintained tools.
- Ability to keep maintenance interesting and evenly applied.
Even with the most detailed foresight and planning, over the lifetime of a code-base, technical debt grows and maintenance becomes increasingly expensive. It is easier to add than remove; large applications are harder to learn; complexity leads to mistakes and introduces bugs. More code, more complexity, more bugs, more maintenance (less flexibility), more training for new team members, more developers and so on. It may not be possible to eradicate these flaws in the development process but there may be ways to reduce, or slow, their effects.
Freshness: a Possible Solution
Practises such as TDD, XP, code review, lint and quality control all aim to minimise the ravages of large teams and time on projects. However, these do little to keep the size of the code-base down. Less code is easier to manage, read, learn and maintain (as long as it stays small). As a concise, well formed, sentence is easier to read and understand; a brief but poorly worded passage is easier to discuss and edit. New developers should be encouraged to get involved and feel comfortable to learn via their mistakes.
In his article The Carrying-Cost of Code: Taking Lean SeriouslyMichael Feathers makes the case for a 3 month lifetime imposed on every line of code (at which point it would vanish from the repository). By being forced to completely rewrite applications over an over: it becomes impractical to make the code-base larger as there simply wouldn’t be time to cover it all.
This approach may be heavy handed, there would be cases where perfectly good code would be rewritten: preventing work in more valuable areas. However, over time requirements change; a perfect solution last week may become less so as the project’s focus shifts. These areas are also ideal for training, a developer can resolve a well understood problem (backed up with API contracts and unit tests) while colleagues can advise and support. Coupled with the easy branching, which tools like Git provide: rewriting, reviewing and merging/rejecting are straight forward.
Code can be graded by its “last modified” or “last reviewed” date, regular code reviews and the ability to monitor “freshness” would ensure all members of the team understand the mechanics of their project.
Reaching the end of a life-span doesn’t necessarily mean it has to be rewritten. If the code is still solving the problem it set out to, in the most efficient and readable manner, then its life-span can be extended. The code can be held up as an example of good practice and made the subject of comparison and code review.