The Non-virtual Interface idiome (NVI) is pretty self explanatory: You don't write public virtual
functions, but public
functions that call a private virtual
implementation function, like so:
class Object{
virtual void v_load();
public:
void load(){ v_load(); }
}
This enables you, the base class author, to check and enforce pre- and post-conditions or apply other functions so the author of deriving classes can't forget about them.
Now when you are the deriving author, you may want to write a base class yourself - let's call it Pawn
- that extends on the functionality of load()
and therefore has to override v_load()
. But now you are facing a problem:
When you override v_load()
, other clients that want to derive from your class, will always overwrite that behaviour, and they can not call Pawn::v_load()
because it is a private
function, neither can they call Pawn::load()
because it is defined as { v_load; }
in Object
which will of course lead to an infinite loop. Additionally, requiring them to do so could lead to mistakes when they forget that call. If I would want them to enable that, I would have to specify the acces to v_load()
as protected
in Object
, which seems like an ugly solution as it would weaken the encapsulation of Object
greatly.
You could of course still override v_load()
to call a new function v_pawnLoad()
, which is then overridden by clients, but that seems very error-prone as a lot of clients will probably overload the wrong function.
So, how can I design Pawn
in such a way that clients can still override v_load()
while keeping the ability to check pre-conditions or call other functions and (if possible) not enabling, let alone requiring clients of Object
or Pawn
to call the base v_load()
implementation?