Context:
In project planning or iteration planning, you are driven by user requirements and change requests (user stories, use cases, SCRs {WhatIsScr}, etc). You need to provide demonstrable change to your project shareholders. You have enough work to fill many more iterations than you have time for.
The Problem:
You have changes that you know that you need to make in order to protect or improve the fluidity of your code, the usefulness of your environment, or the productivity of your staff. However, these are things that are less demonstrable, and which the stakeholders couldn't really understand.
How can you satisfy the needs of the code you're maintaining and the people who maintain it, while also satisfying the needs of your customer.
A solution:
You can't, entirely. What you can do is reserve time for yourself. One way is by setting a percentage. One one project, we use 70/30, on the other it's more like 60/40. The customer gets the largest percentage always. The smaller percentage is our allotment for doing the things we need to do to maintain fluidity of the code and momentum of the team. The developer's time percentage can decrease when code and team are very healthy, or increase when more special care is needed.
Consequences:
If the team or code are really in need of maintenance, you'll likely lose the % you put into fixing thing anyway, but it will go into struggling with increasingly bad circumstances. Ya gotta sharpen that saw.
You offer less productivity to the shareholders, but you try to do their work first, allowing you to be on-time more often. It can make you a hero.
It doesn't guarantee that you'll do everything you want to do, but it will ensure that you are always doing something the team needs. After all "hope deferred makes the heart sick". This can be the best morale booster you can offer your team.
There is a similar strategy named PayForMeatWithCandy.
Lie.
I'm serious. Never underestimate the power of a well executed deception. ;->
- Paraphrased from memory, attributed to Winston Churchill and / or Joseph Stalin: The best truths are covered with a cloak of lies. Applies here?
To force the users to give you your "meat" (IE: structural improvements) to get their "candy" (IE: new features), assert (for each feature) that to get "feature X", you must be allowed to improve "infrastructure Y."
Like, "we can't screen scrape data from header-detail mainframe screens until we implement the data-driven screen scraper." Technically, this assertion is not completely true: We could CopyAndPasteProgramming lots of code and hack together an unmaintainable solution quite quickly. But writing bad code is not an option, so we refuse to talk about it as if it were an option. ;->
-- Some Other AnonymousCoward
Just do your work right. If there's a way to make a feature you're adding go in simply if you refactor up front, first refactor, then add it. If, after adding a feature, there is redundant or grubby code, make it clean. If you run across ugly code in the course of your work, make it beautiful.
Progress will go faster this way, because you are cleaning up where you are actually working, not investing in places you never go.
Then track your progress against stories and tasks in tasks done per unit time, use that for planning. In other words, keeping your room clean is overhead. Don't dedicate time to it, just do it as it needs doing, and measure the effect.
However, I've had at least one situation where the client provided some unexpected userstories, necessitating either changing or dumping existing code. One situation we were faced with required lobotomising a functional area, carefully excising various parts, which we did, but were left with some ugly code which we weren't going to be needing. Well, at least according to the current set of user stories. Then the next planning session they presented a new requirement that relies on some of that ugly code, but not all of it, and part of the story is that this may only be a temporary requirement (a SpikeUserStory)- should we set aside time to do a good housecleaning, build on top of the bad code (refactoring as we go), BurnTheDiskPacks?, or is this a case of YAGNI (the big cleanup, that is)?
Please edit and comment.