Reputation: 4349
I have a group of classes that extend a single abstract class. A subset of these classes need an identical implelmentation of one of the methods, another subset of the classes needs another implementation of the method, and a third subset requires yet another. In all there are about ten child classes, but only three possible implementations of one of the methods. (There are many other methods that the classes implement that have nothing in common.)
I'm trying to figure out the best way to accomplish this. I think what I would have done in C++ is multiple inheritance: create threee classes that implement only this method, then have the children inherit from the appropriate one of those three classes.
Is there a best practice for doing this in Java?
I was considering an intervening layer of three abstract classes, between the main abstract class and the children. Each of the the three inheriting from the main abstract class, and implementing the method in question. Then the children inherit from these threee. But what I don't like about that is what if another method comes along with a similar "grouping" behaviour, and it does not correspond to the three "middle tier" classes? That would get ugly
Is any of this making any sense? I'm writing in a hurry...
EDIT: So, 24 hours after asking my question I have received about a half dozen patterns to investigate. I'm not yet sure that they are all official design pattern names. But I'm going to look into each and then report back (and choose an answer as correct). The pattens suggested so far:
* Delegation
* Bridge
* Strategy
* Composition
* Decorator (if I was choosing on name alone, I choose this one)
I also need to add that the method that is being implemented needs access to nearly all of the private members of the class. So that will factor large in my choice.
Upvotes: 7
Views: 242
Reputation: 8204
Actually, I smell a Strategy pattern here.
You could have that method in the base class delegate to a Strategy that is passed in upon construction. Sub-classes just pass in any one of a set of Strategies as part of their construction. The Strategies themselves could be made available either outside the class, or internally as private classes. This may end up with less classes overall in your hierarchy.
That being said, there are additional smells here, even with my proposed solution. You may want to think at a higher level with interfaces (as mentioned by other solutions) and composition only with no inheritance. Over time I came to the conclusion the inheritance is NOT my friend. Nowadays I avoid it where possible.
Upvotes: 7
Reputation: 1778
First, consider replacing the abstract class with an interface. I don't know if it is possible in your case.
Second, you can delegete the functionaity of your "grouping" method to another class (implementator). Create 3 different classes with implementation of the method (or just 3 different methods in some class) and call them from child classes as needed.
So, the "grouping" method will be defined in each child class but it will just explicitly call one of 3 possible implementators.
Upvotes: 1
Reputation: 72294
The easy quick fire solution without using inheritance would be to abstract the 3 "common methods" to elsewhere, and then just repeat the method call.
If you want to do it in a nice OO way, then have a look at the decorator pattern which may well help here - create your 3 standard classes that implement your three chosen methods and then "decorate" them with the other classes.
Upvotes: 1
Reputation: 691755
Use delegation rather than inheritance. Have all the classes of a same group delegate to a common helper object to implement their method.
Upvotes: 6
Reputation: 17444
If you insist on solving it through inheritance, the bridge pattern from the GoF book could help here (it may or may not be a perfect fit, depending on which domain concerns cause the separation into three implementations). Personally, I'm likely to just put the three method implementations into a helper class and forward the method calls from the classes (what JB Nizet correctly refers to as delegation).
Upvotes: 3