aloisdg/Doccou

Should I use Inheritance, Composition or an extension method?

Closed this issue · 2 comments

During the development of the library Counter, I face an pattern problem. Some documents are archives. Pdf is not. Docx is. Odt is. You can unzip it to read what is inside.
To access to the number of a document's page, I had to.

My class Docx can read an archive. I added to Docx a private method ReadArchive(). Odt can read an archive. I decided to move my method to an extension method. It works. Fine we can move on. Well we could.

  • I don't want to extend anything.
  • Helpers are not really great from an OOP view point.
  • Extension methods can bring some troubles [FR].

Archivist throwing documents

Well, what can I do? I think about two alternatives. I could use Inheritance or Composition. Lets see some code and some logic.

Helper

internal sealed class Doc : ADocument
{
    public Doc(Stream stream)
    {
        string content = Counter.Documents.Helper.Archivist.ReadArchive(stream);
        // do stuff with content like extract the page's count.
    }
}

I, as a document, ask an Archivist to read an archive for me.

Composition

internal sealed class Doc : ADocument
{
    private static readonly Archivist Archivist = new Archivist();

    public Doc(Stream stream)
    {
        string content = Archivist.ReadArchive(stream);
        // do stuff with content like extract the page's count.
    }
}

I, as a document, own an Archivist to read an archive for me.

Inheritance

internal sealed class Doc : ADocument, Archivist
{
    public Doc(Stream stream)
    {
        string content = ReadArchive(stream);
        // do stuff with content like extract the page's count.
    }
}

I, as a document, am also an Archivist. I know how to read an archive.

Multiple inheritance is considered armful. I can understand why (post about this), but not in this case. Can you enlight me?

We cant use multiple inheritance in C#, but we can simulate it. I don't want to add complexity to this project and I dot want to use an antipattern.

I am going to move to the composition pattern. In this case, should I?

I just spoke with @nvareille and we found a solution :)

We used to have :

old uml diagram

And we are moving to :

new uml diagram

We are going to use inheritance in a better way that the one I tought. Hope you approve it.

Glad to be helpful on this case !