Government agencies have often failed at efforts to modernize their legacy systems. Even when the effort is not labeled a failure, it is expensive, time-consuming, and risky. There is a good reason for this: we should not be doing legacy system modernization projects at all.
Why not? To begin with, “modernization” is not a business goal. It does not in itself represent a business outcome that adds value to the enterprise. As a result, its scope of activities can never be clear, the business cannot feel a sense of urgency (and as a result wants to hold off releasing until the system is perfect), and good prioritization and trade-off decisions cannot be made. It is a project that is all risk and no return: there is already a functioning system, so the agency is only risking failure. A modernization effort can never end, since being up-to-date is a goal that slips away as we approach it.
Legacy modernization also does not lend itself to an agile approach – that immediately should be a give-away that something is wrong. We cannot release the modernized product incrementally, beginning with a minimally viable product, because the business will not want to use something that does not at least match the functionality of the legacy system. This means that the scope of the first release is fixed and cannot be adjusted to fit within a time box. The legacy system must be replaced in a single release.
Yet there is a way to modernize a system. The first goal should be to bring contemporary technical practices to bear on the legacy system as is. And the first step in doing that is to bring the legacy system under automated test. A wonderful reference on doing so is Working Effectively with Legacy Code by Michael Feathers. Once the system is under automated test, regressions can be avoided and the code can be restructured and refactored at will. The second step is to re-architect (as little as possible) to make re-engineering pieces of the system efficient. In many cases this will involve creating elements of a service-oriented architecture – or at least finding ways to loosely couple different pieces of the system.
Now to the real point of the exercise. We need to work from real business needs – capabilities that the system does not have. For each capability we change the system to deliver it. We do so in an agile way, and we use our automated tests to feel comfortable that we are not breaking anything. Over time, the system becomes easier to change as components are replaced by more “modern” components. But we never do anything without a good business reason to do so.
In other words, we’ve modernized our system without doing any such thing.