views:

308

answers:

8

I have been assigned the task to refactor a Delphi unit. Wow. 10000 lines of code, no documentation, tons of copy and paste code.

THere are many methods made with copy and paste that could be refactored, anyway I am lost in all those lines, I have the interface section where I can "find my way", but in general what do yuo suggest for tackling this kind of task?

Thanks.

A: 

Does the interface section contain a bunch of class definitions? If so, create a new unit for every class and move each class to it's own unit.
If you use Delphi 2007 or better, you can use the "refactor/Move" option to move those classes to the new (namespace) units.
The next step is splitting the large classes into smaller classes. That's just a lot of manual work.
Once your code is divided over multiple units, you can examine each unit, detect identical code and generate base classes that would be used as parent for the two classes that share similar functionality.

Workshop Alex
+3  A: 

I've faced similar situations. My condolences to you!

In my opinion, the most important thing is that you actually understand all the code as it is today. Minds better than mine may be able to simply read the code and understand it. However, I can't.

After reading the code for a general overview, I usually repeatedly single step through it in the debugger until I begin to see some patterns of operation and recognize code that I've read before. Maybe this is obvious, but thought I'd mention it.

You might also thing about creating a good test suite that runs on the current code.

Robert Frank
Yes, you are right. Refactoring wihtout understanding the code is impossible, anyway it takes lot of time for 10000 records, but probalby dome parts can be skipped.
+1  A: 

I would use some sort of UML tool to generate som class diagrams and other diagrams to get an overview of the system, and start splitting up and commenting like @Workshop Alex said.

Roise
+7  A: 

I think the best thing you can do is to write DUnit Tests for the interface. It forces you to understand the existing code, helps during debugging and it ensures that the interface acts the same after refactoring.

The Top 12 Reasons to Write Unit Tests apply perfectly in your case:

  • Tests Reduce Bugs in New Features.
  • Tests Reduce Bugs in Existing Features.
  • Tests Are Good Documentation.
  • Tests Reduce the Cost of Change.
  • Tests Improve Design.
  • Tests Allow Refactoring.
  • Tests Constrain Features
  • Tests Defend Against Other Programmers
  • Testing Is Fun
  • Testing Forces You to Slow Down and Think
  • Testing Makes Development Faster
  • Tests Reduce Fear (Fear of change, Fear of breakage, Fear of updates)
splash
Can you please redirect me to a link to test units that interact with database data. Unit tests are clear to me, but only for business class units.
http://www.agiledata.org/essays/databaseTesting.html
codeelegance
+1 for creating unit tests for the unit before starting any refactoring. One pitfall you will have to look out for when creating unit tests for existing code, is that it is very easy to lull yourself into a false sense of security. Succeeding tests may just nog stretch the code enough. And if you write tests that force an error condition to check that the error is raised, check for the specific error. Otherwise the test may succeed because an error was detected, but it may not be the error you were looking for...
Marjan Venema
A: 

Use a tool like Doxygen to help you map the code.

Help on that is here

gbrandt
+9  A: 
  1. Get yourself a copy of Working Effectively with Legacy Code by Micheal Feathers. It has all kinds of techniques for safely refactoring code to get it running under a test framework. Examples are mostly in Java and C++ but should be easy enough to figure out.
  2. Install a third-party refactoring tool (or multiple) such as CodeRush for Delphi(sadly no longer developed), Castalia or ModelMaker Code Explorer. Delphi has some refactoring support built in but in my experience it is too limited and tends to choke on very large code bases.
  3. Buy a copy of Simian. It doesn't have direct support for Object Pascal but its plain text parser works well enough. If enough people request support for Object Pascal I'm sure they'd add it. I haven't found any other code duplication detection tool as capable as Simian.

I would also recommend bookmarking http://www.refactoring.com/catalog/ and http://www.industriallogic.com/xp/refactoring/catalog.html.

It also wouldn't hurt to get a copy of Clean Code: A Handbook of Agile Software Craftsmanship by Robert "Uncle Bob" Martin et al. It's easy to recognize bad code. It's much harder know when you're writing good code.

A word of caution: Focus on refactoring the code you need to work on. Its easy to start down the rabbit hole and wind up spending months refactoring code that wasn't immediately relevant to the task at hand.

And save your self some trouble. Don't try to "fix" code and refactor it at the same time. Refactor first, then fix bugs or add that new feature. Remember, refactoring is modifying without changing external behavior.

Resist the urge to attempt a complete rewrite. I learned the hard way that crappy code that meets the user's requirements is preferable to clean code that doesn't. Crappy code can always be incrementally improved until its something to be proud of.

codeelegance
+1 for separating refactoring and fixing bugs. You can even assist here with unit test, by writing tests that succeed because of the bug. They can be removed, or better re-written when they start to fail because the bug has been fixed.
Marjan Venema
This answer is a mine to explore. Thanks.
I personally expereinced on myself the terrible results of refactoring and fixing code. Also refactoring and adding features. Anyway as you say "real refactoring" shouldn't add features. I will buy both books, I aready have them in my amazon wish list since 2 years.... It is time to buy!
+1  A: 

In addition of understanding the code etc, these tools may help refactoring and reorganizing the project:

Model Maker is powerful design, reverse-engineer and refactoring tool: http://www.modelmakertools.com/modelmaker/index.html

Model Maker Code Explorer is powerful plugin for Delphi IDE to help with refactoring, code navigation etc: http://www.modelmakertools.com/code-explorer/index.html

Harriv
+1; those are great tools!
Jeroen Pluimers
A: 

Start out small and eventually do a partial or full rewrite. Start creating base classes to accomplish pieces of the puzzle without changing the output. Rinse-repeat until you have a new, supportable codebase. Once you hit those copy-n-paste routines, you'll have base classes to do the work and it'll really help accelerate the task.

Darian Miller