When I’m maintaining a code base, sometimes I’ll get a big idea about a redesign that will improve the code. And because I strongly prefer to make changes in small steps, this means that the new design may be done in only a small part of the code for some time, living alongside the old design it’s replacing. In fact, the old design may never be completely replaced. How do we feel about that?

I’ll point to a concrete example. I was working with the open source CloudFoundry app called UAA. There were a few tests for the web UI that were relevant to some changes I needed to make to the code, and I saw that the tests had some duplicated code that could be cleaned up. Rather than simply extract the duplicated code to some common methods, I decided to introduce the Page Object Pattern (I’ve had a lot of success with this pattern on other projects, but I won’t go into all the details of how it works here.) You can see the first two tests that I redesigned in this pull request: Rearchitect two integration tests to use page objects.

After that pull request was merged, we had two tests using page objects, but many more that did not. I had agreement from my team that this was a good change, but we then had a mix of different designs in the tests. Even after later converting several more tests in the same test class to use page objects (current version: SamlLoginIT.java), as of now, not all of the tests in the class are using this design, and there are several other unconverted test classes as well. It’s now almost a year later with little further progress, and I’m no longer working on the team. The redesign will probably not be complete across all of the relevant tests for the lifetime of the repository.

We had a great discussion about this at a Legacy Code Rocks meetup (thanks Scott, Chris, Sarosh, Steve, Jacob, and Jeremy). The incomplete evolution seems to be a very common experience for developers (I’ve encountered it myself several times). The general feeling was that doing them is the right decision, even knowing that the rest of the code may never catch up. It was suggested that we should document these design choices so that in the future, maintainers will know which of the existing design approaches should be used for new code and further refactoring. Finding the best place to put this kind of documentation and keep it up to date can be a challenge, however.

So my advice is to make the code you’re working on better than you left it, even if you don’t clean up all the other code.

Thanks to Bruce Ricard for making some great contributions to the UAA redesign mentioned above and for inspiring this post.

featured photo credit: spaceamoeba, CC BY-NC-ND 2.0