user844541
user844541

Reputation: 2958

Injection vs. Inheritance

I have a class that reads some data form a file and then decodes that data.

I am trying to do the class as generic as possible, i.e. I want it to be able to decode any type of data.

The decoder itself is a generic interface.

I see 2 options:

  1. Injection - Get the correct decoder as a parameter in the costructor

    MyReader(Decoder< T> decoder) { _decoder = decoder }

  2. Inheritance - provide a virtual method that will return the correct decoder

    MyReader(); virtual Decoder< T> GetDecoder()=0;

    Users of my class would simply need to inherit that class and implement only "GetDecoder".

The injection solution helps you reduce the number of classes used, while making the user know about the specific encoder.

The inheritance will require many classes, but encapsulates the usage of encoders.

What considered to be a better approach?

Upvotes: 1

Views: 1605

Answers (1)

Tony Delroy
Tony Delroy

Reputation: 106196

I assume your "injection" approach would be storing the decoders via a common base class, and that you're considering alternatives more like:

MyReader(AbstractDecoder& decoder) : _decoder(decoder) { };

MyReader() { private: virtual Decoder<T>& GetDecoder() = 0; };

There are a few considerations:

  • injection mean the client code has to take a more active role in creating and specifying the Decoder, and handling the errors that might happen during its lifetime, while with inheritance it's implicit in the choice of derived class and error handling can be more unified with MyReader errors;

    • with injection, there's a little bit more client awareness necessary in terms of understanding whether the Decoder is copied by the constructor (as you've done), or the caller needs to ensure a lifetime greater than the reader's, whether the same decoder can be passed to multiple MyReader constructors etc.. - all a bit more confusing and error prone
  • injection means the MyReader API could potentially allow specification of another Decoder during the lifetime of the reader

  • with inheritance, you end up with a lot more classes and the client code needs to be a little bit careful to avoid slicing, whereas with the injection it's MyReader itself that needs to be a little careful when storing/copying, but at least that's centralised and therrefore easier to get and keep right

CRTP is another alternative, with compile-time resolution and optimisations (dead code elimination, inlining etc).

Upvotes: 1

Related Questions