Let’s say you’re about to develop a new feature, one that you anticipate will be used by many customers very often. You’ve dreamt up a really cool design, talked to your teammates, built prototypes, mocked up a UI in Balsamiq … hell, you’ve even told your significant other about this astonishing new widget and its potential impact on the industry and, let’s just come out and say it, the ENTIRE WORLD. Sometimes you exaggerate.
Point is, you are ready to MOVE on this thing.
Then somebody tells you that the feature has already been built; it’s part of an older system, but you should be able to implement 90% of what you need just by reusing what’s there. You ask a few questions, and the number drops to 75%, but that’s still pretty good. Yes, the older service was intended for a slightly different use case, and it’s implemented using technologies like punched cards, vacuum tubes and Perl, and there are, like, two people in the world who know the codebase, one of whom is currently lost somewhere in Waziristan (or Alabama; nobody really knows). But at least you can save some effort, because this system satisfies at least 60% or your requirements.
The discussion grows. You offer up some token resistance, but really, what argument can you make? The feature will certainly be built faster if you reuse the legacy code, and then you can move on to bigger, better things. You grit your teeth and rework your design.
Now, let’s take a look at what you’ve done to yourself:
- It turns out that the bits of the feature not covered by the legacy system will require development. This was expected; however, with the current demand on the two people qualified for this development, you will not see the work done for another few weeks. This will almost certainly push your schedule out.
- Some of the uncovered functionality cannot be developed on the legacy system; it wasn’t built for your use cases, so some things just don’t fit. You need to build out bits of the original system you intended to build anyway. Your project has become more complex as a result.
- Rather than working in technologies you and your team have been using and building up for the last few months, you now need to learn the ins and outs of the legacy system, from user interface to API, and maybe even the schema. That’s more time spent digging rather than building.
- The work you had planned in the previous design would have been applicable to many other projects; instead, you are now building special routines to munge data between new and legacy formats. Rather than contributing to the future of the software base, you are most likely adding single-use plumbing fixtures.
- Your team, the software developers who were previously ready to rally around you as you all set off on a new adventure, are now dreading weeks of hacking ugly adapter code together. You’ve moved them from the Happy Innovation Land theme park to a run-down subdivision of Boring Practical Reuse-ville. This may make monetary sense, but is not always the right move if you are trying to hold on to talent.
I’m not saying that adapting features from legacy systems is always the wrong thing to do. However:
- there are times when old software that seems like a perfect fit will burn you in the end,
- there is always a cost to disrupting an energetic team that has built up momentum, and
- allowing developers to innovate and to exercise autonomy are leading factors in software developer retention (see http://jitm.ubalt.edu/XIX-4/article1.pdf). That’s science, baby.
In the end, maybe legacy reuse really is the best thing in your situation. Just be sure to weigh all factors and opinions carefully before forcing a team in this direction.