Small stories, legacy code, and scaffolding

Working with legacy code, code that is older than many of the developers working on it, can be a real challenge. I worked with some code that was written decades ago, when best practices for software design were less established. It had huge modules, with no thought to modular design and the Single Responsibility Principle.

This had a bad effect on testing, since it was not easy to build unit tests so that individual modules could be tested when they changed, as is popular with Continuous Integration.

But even trying to break stories down into sprint-sized pieces was difficult. Good Agile practice requires implementing a change in such a way that it can be demonstrated at the end of the sprint. When you have a complicated process that is all taking place in one or two huge modules, this can be really difficult. If the whole change is going to take several sprints to complete, then the amount of it that you can accomplish in a single sprint may be just enough to ensure that the product does not work at all.

There are some ways around this. The first is to add temporary messages to the product. For example, one product I worked on had a parameter library that the customer could use to customize the operation of the program. Each new parameter needed changes to a parser, several control blocks, various screens, and an editor. And all this was before we got to the module that actually used the new parameter. So how do you demonstrate that the new parameter editing is working, when you do not yet have the code that consumes the parameter? You can add a temporary message that displays the value of the parameter. Then in the sprint review, you can demonstrate that if you edit the parameter, its value changes.

But if you ship the new code with the product, you do not want the customer to see the message. You can handle this with special debug flags. There are various ways to do this. If you have a parameter library, like the product I mentioned, you can have special parameters that set debug flags. In systems like MVS (IBM mainframe), where you have control statements that map external file names to the internal names the program uses (DD statements), you can have special dummy file names that, when specified, act as flags.

Once you have a way to specify debugging flags, you can turn your temporary message on and off. And you can even change the control flow of the program. Perhaps the change to the format of a parameter causes the rest of the program (the part not yet changed) to fail. Your debug flag can make the program display the message showing the new value, then exit the program. If the flag is not set, the program processes the parameter the old way.

My experience with teams have been that they usually do not like the idea of this kind of scaffolding, because they feel it is a waste of time to put code in during one sprint, and take it out in the next. These concerns can be reduced by setting up an easy-to-use infrastructure for debugging scaffolding. If you have a way to specify debugging parameters, you can have a module that can be called anywhere in the program to find out if a particular debug flag is set. Similarly, if you have a good message infrastructure, it is easy to issue debugging messages. Unlike messages and parameters that are for the customer, these debugging aids do not have to go through the normal approvals by technical writing, support, marketing, etc., so there is not a lot of work that is undone and wasted when you remove them.

The other complaint I hear sometimes is that people question what is wrong with just leaving the story open and in-progress for several sprints. They see it as merely a bookkeeping issue. But it is more than that. A large change is going to involve a number of modules. If these are apart on the workbench for several sprints, this gets in the way of changes other team members may need to make to them.

Even more important is the issue of agility: one of the benefits of Agile development is that the team can turn on a dime when requirements or priorities change. If something of a higher priority than your multi-sprint story comes along, and you have the change half-implemented in a bunch of modules, you have to stash your half-modified code somewhere, work on the new story, and later try to resynchronize your saved copies of the modules with the ones that were changed by the new story. That is the kind of busywork that nobody needs.

Scaffolding like this can make it a lot easier to break large changes down into manageable pieces. The toughest part is getting your mindset right, and realizing that even if you are putting in a little code, only to take it back out the next sprint, the overall benefits are worth it.

Update, 2015-08-03: Here is a good article by Jim Bird about some of the hazards you have to be aware of when using feature flags and scaffolding:


Leave a Reply

Your email address will not be published. Required fields are marked *