Design Patterns – How to Replace Inheritance with Composition

compositiondesign-patternsinheritanceobject-oriented

I've recently read several articles about the advantages of the composition over inheritance. Their authors said that you can always replace inheritance with composition (to be precise, they say they don't know such situations where it can't be done). However, I can't think how to do this in the following case:

abstract class Reader
{
    public Int32 ReadSum()
    {
        return this.ReadValue() + this.ReadValue();
    }

    public Int32 ReadSub()
    {
        return this.ReadValue() - this.ReadValue();
    }

    public Int32 ReadMul()
    {
        return this.ReadValue() * this.ReadValue();
    }

    public Int32 ReadDiv()
    {
        return this.ReadValue() / this.ReadValue();
    }

    public abstract Int32 ReadValue();
}

class RandomSource: Reader
{
    public Int32 ReadValue()
    {
        return Math.RandomInt32();
    }
}

class UserSource: Reader
{
    public Int32 ReadValue()
    {
        return Console.ReadInt32();
    }
}

Is this at all possible?

Best Answer

This example is a bit contrived but here's one way.

You seem to have things going on here - operations and reading. The reading should be done by Reader and the operations can be performed by a different class.

class ReadOperations {

     private Reader reader;

     public Int32 ReadSum()
     {
       return reader.ReadValue() + reader.ReadValue();
     }

     public Int32 ReadSub()
     { 
        return reader.ReadValue() - reader.ReadValue();
     }

     public Int32 ReadMul()
     {
       return reader.ReadValue() * reader.ReadValue();
     }

     public Int32 ReadDiv()
     {
        return reader.ReadValue() / reader.ReadValue();
     }

}

interface Reader {

  public Int32 ReadValue();
}

class RandomSource: Reader
{
    public Int32 ReadValue()
    {
        return Math.RandomInt32();
    }
}

class UserSource: Reader
{
    public Int32 ReadValue()
    {
        return Console.ReadInt32();
    }
}

Depending on what you want there are other ways to do this.

You should have to find a way to inject the reader - probably with a constructor.

Disclaimer - for practical purposes you don't "need" to use composition, but doing so is extensible and you should use it whenever you think your program can evolve in a certain direction.

In this case, if you think your operations will evolve independently from the way you "read".