Click here to Skip to main content
16,011,608 members
Articles / All Topics

Inherit or Compose.. Hmm..

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
1 Nov 2010CPOL2 min read 5.4K  
Inherit or compose?

When designing your domain/classes, this is one decision that always results in conflicts within teams. Whether to inherit from a class or to compose that class. This is fairly subjective but here are few pointers for discussion.

Let's take this code for example:

Java
public class GiftCollection extends HashSet {

    public Gift getRandomGift(){
        List giftList = new ArrayList(this);
        Collections.shuffle(giftList);
        return giftList.get(0);
    }
}

It is a collection of gifts that is represented as a set. The additional behavior from a set is that it can give you a random gift. It looks fairly straight-forward and would work in an even more straight-forward manner. Let's look at a usage of this.

Java
public class GiftSelector {

    GiftCollection giftCollection;

    public GiftSelector(GiftCollection giftCollection) {
        this.giftCollection = giftCollection;
    }

    public Gift selectRandomGift(){
          return giftCollection.getRandomGift();
    }
}

This is a basic usage of the GiftCollection provided earlier. If one looks closely, though the two classes look very similar and doing similar things, there are basic differences between the two.

GiftCollection inherits a HashSet and extends to the behaviour by adding another method getRandomGift to it. However, GiftSelector decided to contain a GiftCollection and delegate few calls to it.

I've always preferred the latter approach for the following reasons:

1. The classes (both superclass and subclass) are much more flexible to change.

In this case, if GiftCollection decides to change the signature of the method getRandomGift(), it would not have an effect on the callers of GiftSelector, since it wraps the method call.

But any change to the Set implementation would affect the API of the GiftCollection class, without its knowledge. The users of GiftCollection have to change their code, though there has been no apparent change to the class. This is not an ideal scenario.

2. Easier to test

It clearly shows that GiftSelector is much easier to test than GiftCollection. One can easily mock the dependency of the class and unit test the code. Whereas, in the case of inheritance, most mocking libraries do not provide a way to mock super classes. So it's difficult to test in isolation.

3. Polymorphism through Interfaces is more flexible

One of the reasons for inheritance has been to reduce code and take advantage of polymorphic behaviour. Interfaces provide a more flexible way to achieve the same result. Composition coupled with Interfaces present a better alternative to achieve polymorphism.

This is not to say that one should not use Inheritance.

When modeling your domain, Inheritance should be used in case of a direct ‘is-a’ relationship. It should not be used only to achieve code-reuse or polymorphism.

Prefer composition over inheritance, unless you have good reasons to not do so...

I would love to hear your thoughts on this.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --