views:

226

answers:

4

This is a C# question, but really could be language-agnostic

I have inherited a large object model (100+ types), with a hierarchy of objects that 'own' 0..n of other typed objects that all share a base (where there is a 'relatively' strict type hierarachy).

I want to start decoupling these objects though inheritance to put together an IoC based system to start to implement some unit tests with greater depth than currently exist.

Where would be the best place to start?

I can start at the top of the hierarchy, which is quite simple but would have the least initial benefit, and would be quite rote until I get further down the chain, but that would require me to implement a few cludges at the base object to overload function signatures to accept base interfaces until I get full coverages.

I could start at the bottom of the hierarchy, which would be much trickier, as there is alot more interaction between classes down there, but would 'force' us to take a more holistic view of the refactoring.

I could also start at the Base objects (those which all the objects are inheriting from) which would start the process off at the logical point, but would almost certainly create an uncompilable application until we get to swap out all the objects inheritances and function calls.

Any thoughts?

+2  A: 

if you can complete the entire process in a reasonable amount of time, start with the bases and go through the whole thing; the app will be broken until you are done

if you must keep the app working in the meantime, start at the top and work your way down a few classes at a time

i would look at the bottom-up perspective also, but doubt that it will be a practical way to implement since it likely will break everything and take longer than the other two approaches, but Your Mileage May Vary ;-)

the base questions are:

  • how long will each approach take?
  • will each tactic eventually end up producing the same final code?
  • how important is it to keep the app(s) working while the transformation is being completed?
  • do you have enough unit tests to trust a massive refactoring?
Steven A. Lowe
wouldn't know the answer to 1 unless its done.. I guess the right question there is 'how long am I prepared/allowed to invest?'... before i am summoned into the conf room;)
Gishu
+1  A: 

This may be a little too academic, but there was a lot of research in the mid-nineties on how to automatically refactor large class hierarchies, for example by figuring out interfaces that are commonly used, etc. While this may not solve your problems, it may give you a good option of where to start or at least some interesting perspective on these sort of problems.

A first paper in that chain was Godin and Mili's "Building and maintaining analysis-level class hierarchies using Galois Lattices" (google and you shall find the PDFs), and there was a whole series of following papers (see papers that cited this) on different tricks.

Uri
+1  A: 

Start from the top and create smaller hierarchies, using delegation instead of inheritance as you move down. Use the strategy pattern to remove Behaviors from classes in the hierarchy.

grepsedawk
+1  A: 

I'd say

  • Take a good look at the existing design.. formulate an approach... get a computer to try it out. (Kent Beck's guideline.. no design discussion should stretch beyond what was it... 30 mins. Once you hit the barrier, grab a machine, code it up and see if it works.)
  • After a timebox of one hour (or more as per taste) if you feel you're making progress... persist. Else back to the drawing board.

Just get started... instead of spending BDUF time trying to figure out the way.. it'll clear up. Of course, having a safety net of good ATs would be vital.

Gishu