Tuesday, September 21, 2010

Moving an existing class into a separate file

Large files are just as evil as large classes or large functions. And for all the same reasons. Inevitably a large file can become a black hole, just like a large class or function can be. More and more classes get piled into one file, until you have to scroll pages and pages to find the class you want. I realize with the right tools, what file a class or a function is in can be less important because you can just "go to definition", but when you attempt to make sense of more than just one class, unnecessary junk surrounding it can create more confuson.

In addition, mega-files have the tendency to confuse dependencies. For example if you pile ZApple, ZOrange, ZKiwi, and ZPassionFruit into the same file "fruit.h", every file that only uses oranges, needs to include fruit.h. This increases compile times. Plus the larger files tend to have more people working on them at the same time, creating merge conflicts.

One class per file solution tends to be the better one, unless the classes are very small.

As with splitting up a large function, there is a simple check list to follow (I'm assuming C++ here)
  1. Find the class that we want to factor out (let's say it's called ZOrange, and the files it's defined in are fruit.h and fruit.cpp)
  2. Create the files that will contain the newly factored out class (let's call them orange.h and orange.cpp)
  3. Move the contents of ZOrange from fruit.h to orange.h
  4. Move the function definitions of ZOrange from fruit.cpp to orange.cpp
  5. Create the appropriate #ifndef / #define / #endif in fruit.h, to make sure it only gets compiled once
  6. Add orange.h and orange.cpp to the project
  7. Add orange.h and orange.cpp to source control
  8. If needed, include orange.h from fruit.h (or better yet, forward declare ZOrange and include orange.h from fruit.cpp)
  9. Add references to orange.h from all files that need it
  10. Remove references to fruit.h in all places where we only need access to ZOrange (this you can only do if you have domain knowledge, so leave that step alone if you know nothing about the code, or want to save time). 
  11. Build the solution on all relevant platforms to make sure nothing is broken
  12. Enjoy the fruits of your labor (and the reduced size of the fruit.h file)

    No comments:

    Post a Comment