views:

199

answers:

7

We have a C++ MFC application (SLOC is ~200000 if it matters). It was written very quickly during the dot-com era with little thought given to extensibility or scalability. In the intervening time, it's become a mission critical product that we distribute to customers.

Right now, we have two great developers maintaining the codebase, but with no QA and very scant unit tests. This means that they can only add small features when requested by customers and perform bugfixes when needed and then push out a new version. This is our development process and it's not going to be possible to change it anytime soon. However, it's also become very clear that the addition of any kind of new, big feature or capability is going to require a significant redesign/re-architecting.

So, my very broad question: is the refactoring and redesign of a codebase on this scale with only two developers and no QA ever possible or advisable? Does anyone have experience with this sort of situation and how to work with limited resources like this?

+3  A: 

I'd follow this thread:

http://stackoverflow.com/questions/128498/what-are-the-best-code-refactoring-strategies

  • Have unit tests (otherwise it is nigh-impossible to effectively refactor)
  • If you don't have unit tests, you can possibly record some.
  • formally deprecating methods you intend to remove can help
  • Eclipse has lots of features that can help (renaming/repackaging, promoting locals, demoting fields, etc.)
  • I would encourage code reviews; isolate your refactoring changes to a handful of sequential commits and review the diffs.
  • I would also aim for low-hanging fruit, and think small; huge refactorings carry a lot of risk and should not be undertaken lightly.

Looks like from your requirements, this is good advice. If this is code like I'm imagining: a sprawling mess with ubdocumented features and requirements and plenty of code susceptible to side effects, you'll really need the unit tests.

I wouldn't rewrite the thing from scratch until you really understand what the application does and how it does it so you really do rewrite it correctly. Too often I see developers rewrite something with the exact same (or worse) design.

altCognito
A: 

Sometimes writing from scratch is less expensive than refactoring the whole thing. Though it depends on the project architecture. I would make a fast decision for refactoring before the codebase gets more and more complicated. Or else I would write from scratch if it's too late.

Emre
Writing from scratch is almost never a good idea, especially for a whole system. Did you mean re write parts of the system from scratch?
Greg Domjan
Yes, I said it depends on the project architecture.
Emre
+2  A: 

I would suggest that you identify the problematic modules that exist within your solution and try to refactor / redesign based on importance one at a time.

It's not realistic to have a stop to bugfixes and features so i suppose branching on your version would be advised and once changes are done and confirmed merge with the main source files.

That way bugs and features that are critical and high priority would be added to your main source while you work on the refactoring /redesign in your branched code. Won't be easy and it's expected to be done on free time.

Konstantinos
+1  A: 

Yes, it is sometimes possible. You will benefit from using a revision control system that handles branching well and supports changelists so that when a change requires altering multiple files, all the changed files are saved as a unit, and can be backed-out or migrated-to-production as a unit. Perforce and git are two such.

Thomas L Holaday
+1  A: 

It's going to be very difficult with two developers who are already busy maintaining the old code base. There's going to be a period of no updates unless you're willing to throw additional resources at it, for a while. One possibility is to develop a new design, implement the shell of that design, and have it call the existing logic in the MFC application wherever possible. This will place an abstraction layer between the "old" and "new" code without requiring a complete rewrite all at once. It will introduce its own problems, but you can start building on the new platform while gradually gutting the underlying base.

flatline
+1  A: 

You might also want to check this once: Things you should never do - Part 1

Naveen
A: 

In many cases it all boils down to a business decision. When you actually have a big feature implementation request, you can sit down and see whether the through-life costs support refactoring.

It's always nice to work on cleaner code, but, if the codebase has a limited lifespan, you may not be able to justify it. Sometimes refactoring is presented as some kind of religion, but one must be pragmatic. I'm seen teams undertake whole scale refactoring on a codebase that was never touched again!

dommer