Recently one of our account executives asked me an interesting question. He had been contacted by an ISV who was slogging through a rewrite of a very large (millions of lines of code) VB6 app to .NET. And like many if not most companies who attempt rewrites of very large applications, at some point the pain, cost, time, and risk began to be largely untenable and they began investigating tools to address the problem.
So of course they came across the Visual Basic Upgrade Companion, which can save 75% of the time and cost of a manual rewrite. But they had a question.
See, during this rewrite, as people are wont to do, they decided to redesign the forms/screens. The nature of software development is that no one likes what they have as soon as it's done, and they dream at night of writing new, perfect, glorious code. So the question was: can we use your tool and STILL redesign the screens as we convert from VB6 to .NET?
Agile or fragile?
I'm old enough to remember the good old days of software development when we thought we could figure everything out in advance, before we wrote a line of code. We called it the waterfall model. And like going over Niagara Falls in a barrel, it was rarely a pleasant experience. Budgets were blown to bits, schedules slid to infinity, vast quantities of cash were squandered, and careers were destroyed from the false premise that software was like construction so you shouldn't start work until you had a perfectly detailed blueprint.
Over time the consensus shifted from planning complete applications up front to planning chunks of work--milestones or blockpoints--that were more definable and predictable. The trend to shorter and shorter planning windows eventually manifested itself as agile development where people might consider you old-school if you're thinking much farther ahead than a week from next Thursday.
Don't get me wrong; agile is great. It's great because it actually works, at least better than all the alternative approaches to development. Agile nicely allows for the reality that software is intangible, and as such doesn't work well with systems developed for tangible projects like building bridges, apartments, and convenience stores.
If agile means anything, it means narrowing the scope of work to a small discrete unit with a usable result. If agile was used to build houses, you'd build a kitchen before you built anything else. "We got no place to sleep!" "I know, but at least you can cook!"
Agile = get it done.
Waterfall = who knows when it will be done?
The agile migration approach
Now I'm sure a lot of agileistas will lose their minds over the next thing I'm going to propose, but so be it. Bring it. Here it goes:
The most agile way to migrate legacy apps is to move them intact to a new language and platform, with no changes.
Ok, it's not pure agile in the sense of writing new code in two week sprints, putting those into production with CI/CD. But that's not what a migration project is. An ideal migration project quickly and efficiently gets the same app running on a current/supported platform in a current/supported language. And while it's not a waterfall project, it is a big-bang project, in that everything normally gets released at once.
The process is pretty straightforward. Once you've used automated migration tools (VBUC or WebMAP), you have a whole new source code tree to work on. And it probably won't compile right away. Compile errors will result from mismatches between the old language/platform and the new one. You might have used a property of a control in VB6 that has no corollary in .NET. Those property gets/sets will have to be rewritten to something different--something that will work in .NET.
We recommend a approach where a team member is designated as the go-to person for a specific type of error--array re-sizing, for example. That individual goes through the entire code base just fixing those problems, ignoring others. This is arguably faster than trying to get a single C# file or project to compile, since errors in one file are likely to be repeated in other files. Sprints could be planned around getting to zero compile errors for each class of error.
Large migration projects can take months, during which time the existing application may require maintenance or updates. These changes can be merged into the migrated code through a process we've perfected over the years. When the migrated application is close to complete, however, it may be best to integrate those changes after it is finished.
The less agile migration approach
Let's return to the question my colleague asked me, about redesigning the screens as part of the migration project. To be specific, given they want different screens for their migrated app, should they do that work during or after the migration project?
The advantages are numerous. For one thing, once the existing app is migrated to the new platform and validated, they can put that app into production immediately, and--since the user interface (ie screens) haven't changed--they won't need to retrain their user community. Now the screen redesign can begin using the new language and platform, and no doubt better tools. Those changes can be rolled out incrementally to the users. Each new screen opens the door for some selective and thoughtful refactoring of the associated code. Build classes. Remove cut-and-paste repetitions. Tidy up names and comments.
Redesigning the screens as part of the migration project sounds like less work, but it's really not. It just shifts the point at which you do it. And adding this step to the migration project defeats one of the key benefits of moving like to like: a migration project has a perfect spec. The spec is the original app. So validating the new version is simple: it has to do exactly what the original app does. Changing that paradigm creates a new app with nothing to compare it to. There's nothing wrong with a UI refresh--but do it after the migrated app has been put into production, so you can create an appropriate QA test suite for each new screen.
Here at Mobilize.Net doing migrations and building tools for migrations is all we do. Over the years we've found the most predictable and least risky approach to these monster projects is the process described above.