Software development is a team sport. All the people involved are in the same boat. Managers blaming developers for being lazy and developers spreading jokes about managers who don't understand what needs to be done will not help. In my work, I often interpret between the languages of business and technology so that the people can work together to achieve a common goal. By this blog series I will try to help non-coders collaborate better with their coder colleagues.
You would like your team to deliver more business features (stories) within the available time, but the developers keep mentioning "technical debt", "legacy code", the mess the previous team left behind, a need to upgrade to a new version of the technology being used, or switch to something "modern", a need to do "refactoring" etc.? How to have your cake (deliver business features) and eat it (let the team improve the technical aspects of the solution)?
A tempting idea of many project managers, product owners or others in charge of planning software development activities is to get rid of the "inconveniences" once and for all: Why not devote a sprint, a month or some other period of time to kill the tech debt so that after that period we could concentrate on the business features? Unfortunately, I think it is not the best way to tackle this. The problem is that the list of "all the tech debt" is infinite: There will always be some technical issues that could be improved in any software product, both small and big ones. We need inputs to prioritise the tech debt and the priorities change in time.
What is even more important: New tech debt keeps coming. Why? Firstly, new features increase the complexity of the code, so additional technical measures (e.g. abstractions, refactorings) may be needed to keep the complex code maintainable. Secondly, as multiple changes and additional features pile up, the internal structure (design) of the product may become inadequate, so again some restructuring (refactoring) may be needed after some time. And finally, there are external factors like new security vulnerabilities discovered, limited time of support of certain versions of 3rd party software libraries, APIs, frameworks or platforms the product depends on, requiring an upgrade even if there were no changes to the business functionality.
So like it or not, fighting the technical debt is not a one-time mission, it is a chore that should stay visible in your future sprints (planning iterations). There should be a constant percentage of the development team capacity reserved to be spent on technical debt items in every iteration. For greenfield projects the percentage may be lower (but very soon after first code is created it will be above zero), for legacy projects where technical debt reduction was neglected for some time, it should not be a surprise that it may make sense to do one technical task for each one business feature change. And when the deadline (sprint end) is approaching, in choosing the items to be pushed to the next iteration, we should maintain the ratio (i.e. NOT move only the tech items to the next sprint).
In my opinion the best approach is to let the developers alternate the business requirements with the technical tasks. When a business requirement has just been implemented, the developers have the technical impediments that have prevented them from implementing the feature faster fresh in the memory, so they can naturally prioritise those tech debt items. They can also address the needed refactoring caused by the recently implemented change much more easily than later. It works in the other order as well: When the developers know what business requirement is about to be implemented next, they can choose to prequel it by killing a tech debt item that will make that particular feature easier to implement. This way we can prevent wasting the effort on some other technical task that may not bring as much benefit, a.k.a. overengineering .
For the alternating to be possible, both the business requirements and the tech improvements should be small enough so that we can put many of them in a development iteration (sprint). That is in line with the principle of fast feedback that is at the core of all agile methodologies. I will probably write about tactics for making small tasks in a later episode of this series.
Does this make any sense to you? Let me know on LinkedIn.