views:

91

answers:

2

I would like to get the stackoverflow community's opinion on the following three design patterns. The first is implementation inheritance; the second is interface inheritance; the third is a middle ground. My specific question is: Which is best?

implementation inheritance:

class Base {
  X x() const = 0;
  void UpdateX(A a) { y_ = g(a); }
  Y y_;
}

class Derived: Base {
  X x() const { return f(y_); }
}

interface inheritance:

class Base {
  X x() const = 0;
  void UpdateX(A a) = 0;
}

class Derived: Base {
  X x() const { return x_; }
  void UpdateX(A a) { x_ = f(g(a)); }
  X x_;
}

middle ground:

class Base {
  X x() const { return x_; }
  void UpdateX(A a) = 0;
  X x_;
}

class Derived: Base {
  void UpdateX(A a) { x_ = f(g(a)); }
}

I know that many people prefer interface inheritance to implementation inheritance. However, the advantage of the latter is that with a pointer to Base, x() can be inlined and the address of x_ can be statically calculated.

A: 

If there are multiple derived classes all of which using the g(a) transformation on the input, then I would go with the first option, just to avoid repeating the code. I think that is a higher goal than optimizing element addressing.

Jeffrey L Whitledge
A: 

I would say that no one technique is inherently better than the others. They are all useful in different scenarios depending on the context in which they are used.

If you are implementing the Composite Pattern and most classes will use the same implementation then implementation inheritance is probably the way to go. It will allow you to refine the implementation for those classes that need it, while sharing the code for those that do not.

If you are implementing the Visitor Pattern where it is likely that each class' method implementation will be completely different, then interface inheritance may make the most sense. In this case, a base class implementation will probably only be used by a single class.

I can see your middle ground example being useful if you are inheriting a project that wasn't designed using object-oriented techniques. Maybe you need to refactor it while adding new features, and can use this as a way to get the legacy code to interact with new code that does use an object-oriented design. This is more of a compromise than an actual "best practice", but we all have to make them to ship products...If I can think of a better/more concrete example I'll post it.

adam