Sooner or later in the lifetime of every actively developed code base one reaches the point where it seems to get harder to iterate. Features take longer to be implemented, short-cuts taken in the past rear their ugly head etc. This phenomena is so common that we techies gave it a catchy name. We call that technical debt.
Debt? What do you mean?
I guess this terminology came into play because we wanted to convey that without maintenance future development gets more "costly". We all remember that last time when someone "in charge" declared a certain user facing feature to be of the utmost importance and that is it better to have it working "somehow" but in a short time instead of doing it "right". So every time we make this consideration between a thorough and correct implementation of a given feature versus a "quick and dirty" solution we actually decide between "paying" the costs (e.g. manpower, development time, QA) up-front or rather in rates. Assume for example that a given user story would take your team 10 hours to implement. If you have an increased cost due to the lack of maintenance of 10% than the story will now take your team 11 hours to implement. So one extra hour goes to technical debt.
This picture is lacking though. The nasty thing about technical debt is that no amount of time will pay it off. It's not a loan you take for some fixed rate and then just re-pay it eventually. It's rather an "extra" you have to pay indefinitely for all life-time of your code base (i.e. product). But fear not there are still strategies you can employ to cope with that whole technical debt thing.
Strategy 1: increase resources
The most simple solution that comes to mind is to have more people shoulder the given problem. Yes you will have to employ more people or shift them in from other teams but still more hands means faster iteration. The question though is to what extend this strategy scales. If you neglect maintenance completely and just power through your feature wishlist with an increased head count you may still experience a decline in overall productivity. Also increasing the real monetary costs of your team / department does not make you super popular with the next layer of management above you. So you better have some solid success stories on hand for the long run.
Strategy 2: improve maintainability
So our main problem is lack of maintenance or the level of maintainability, right? Why don't we just improve on that regard? But how can we improve a thing that isn't measured in the first place? We still only have our developers that tell us that a technical debt entered our picture but we don't know how big it is or if what they say is true at all. Luckily there are a few automated processes one can employ. A good idea may be to invest some time into setting up a solution like SonarQube. It can scan your code base and check for common signs of code smells by applying a fixed selection of rules. At the end it can supply you with KPIs and their development over time. Useable figures may be the overall complexity of individual methods in your code or the amount of test coverage. In theory you could then advice your team to just use the output of a tool like that as a task list that would magically transform your code base to superb maintainability in the end.
Of course that is not so easy in the real world (tm). Automated rules and figures can only give you a hint or guide your team to smelly areas in the code. Still the main problems lie in meta issues that go beyond the scope of simple code analysis. I would rather propose a rule of thumb that exempts every individual developer from blindly following the output of your sonar server as long as he can name a meta issue and a way how he would fix it.
Still in the end that means tackling technical debt in this way further increases our cost of iteration. Until the debt has been payed off you will have to not only pay extra for it's existence you will also have to allocate time frames where actual maintenance happens.
Strategy 3: don't take short-cuts
If you are in the lucky situation that no (known) technical debt exists (yet) you can as well just try to avoid creating it in the first place. This is easier said then done though. Usually you will always have to set some deadlines for the fear that nothing may be delivered over all (sooner or later dooming you and your team of course). But let's face it even a good development team may be bad on estimation once. So short-cuts will be taken eventually and of course they could leave you out of the picture at that time, grinding on in secret. The problem now is that you always had this green traffic light in your mind and suddenly some time later it immediately goes to red without any warning beforehand whatsoever. Of course your team will find a way of blaming you or your customer or some other management entity for the situation then. So not taking "short-cuts" is a noble goal but without any further strategy this goal may never be realized and as soon as you find yourself in debt it really doesn't matter that much any more.
Strategy 4: install a (technical) product owner
One way to materialize the goal of Strategy 3 according to our believe is making someone responsible to keep track of the whole picture of features vs. maintainability. This could be you or some developer with management skills or someone new to the team. One prerequisite though is that this person needs to have the ability to understand in what state the current code base is and how proposed future changes would affect that state. It also would help if your developers would see that person as being tech-savvy enough to not be bullshitted.
But how does having someone like this improve our picture? Well a product owner in the end should have a strong say about the feature list of the product. He should be the person that takes incoming feature requests and ways them against business value as well as cost of implementation and maintenance. We always see the dreadful story repeating itself where features are implemented at great costs just to get some check marks on a perceived wishlist an imaginary customer may have. An ideal product owner would spot such situations early on and deny resources being allocated to that. His inner alarm signal would be triggered whenever random manager comes into the room saying something along the lines of "...we need this feature ASAP to close that deal.". Deals are never closed on the basis of technical implementation detail...
What do you think about technical debt? What strategies do you employ to tackle it (if any)? Please feel free to comment or discuss on our mailing list.