YaK:: WebLog #535 Topic : 2008-03-06 06.47.15 matt : a standard set of refactoring steps for C and C++ [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   
  [Back to weblog: pretention]  
[mega_changes]
[photos]

a standard set of refactoring steps for C and C++

While working on a large C++ project with another consultant, I started trying to codify some iterative steps for what we have been doing.


I recently rediscovered something instinct told me 7 years ago when I was working on a C++ called Hailstorm. I was retrofitting unit tests into that code base (pairing with Brian Siepert), and reasoned that starting at the lowest level components would be the best place to start. My reasoning at the time was that unit testing at a higher level would be suboptimal if the lower levels had bugs. On a side note, we found a real bug with every other unit test that we wrote (mostly in poorly written copy constructors), most of which prevented the product from finding exploitable bugs. I had hit a wall with the bug I was finding in the 70% code coverage I was getting using my WinRunner tests, and decided to take the testing down a level of granularity. It was *extremely* effective, as far as I was concerned.

Without initially remembering that experienced, I reasoned it out this time due to the difficulty of testing we are having. Some of the dependent objects are not only difficult to create/mock, but also have nasty static initialization in them (or via their transitive dependencies). This has led me to the same conclusion, but at the macro level in this particular instance:

Getting the dependent objects in other components clean becomes a near-necessity for getting the targeted code clean and tested. We have spent so much time trying to refactor toward testability only to hit a brick wall due to said dependencies.

As such, here is the way we are working now:

foo(a)
{
  return a.getB() + a.getC();
}
foo(b, c)
{
  return b + c;
}

LeafClass::foo(Bar bar, int a)
{
   return bar.frobnikate(a);
}
Bar::foo(int a)
{
   return frobnikate(a);
}

Note that this could be done with C (or whatever other language as well), replacing class with struct and file, etc.

phew. I'm going to do some more in-depth applications of these practices on open source and try to turn them into some small case studies for potential magazine articles and/or talks.

Discussion:

showing all 0 messages    

(No messages)

>
Post a new message:

   

(unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
(last modified 2008-03-06)       [Login]
(No back references.)