Monday, July 26, 2010

From static class to real object, and then from inheritance to composition

I'm refactoring Scisr, an automated command line refactoring tool, because it uses static classes as collaborators for the various Operation objects (Rename File, Rename Class, ...). In my refactoring, the static classes are becoming objects one at the time, and I inject those objects into the Operation ones.

Because of the quantity of collaborators, I am at the point where constructors are taking 5-6-7 arguments. But by no means this is a failure of Dependency Injection.

Using static classes means hiding the dependencies under the carpet, because you'll never know which objects access a static class from the signature of its constructor or of its setters. You must dig and look for :: operators (in PHP; in Java, for [A-Z]{1}[a-z]+\. or something like that; I'm glad Rasmus used a different operator for calling static methods).

Thus this refactoring uncovered a new code smell: the Operation objects have too much dependencies. Probably this is because common functionalities were refactored in abstract base classes instead of intermediate objects. This solution has great limitations, because the collaborators of an abstract class still must pass from the subclass constructor.
Furthermore, abstract base classes are not orthogonal: you can only inherit from one of them. Different functionalities end up in the same superclass only for convenience and not for cohesion.
The next step will be changing the design from this:
to this:
Possibly with more than one Collaborator, one for each use case where a subset of the old collaborators Db... were injected together. With this solution I hope to eliminate the explosion of the constructors of Operation classes.

No comments: