Talk:More C++ Idioms/Non-Virtual Interface

This idiom requires serious rework! Three *distinct* patterns are incorrectly mixed together:
 * 1) non-virtual interface
 * 2) template method pattern
 * 3) before/after invariant checking

1 is a statement about not having virtual functions in the *public* part of an interface and *nothing* more. Reason: distinguish between two major audiences of the inerface, implementers and end-users!

2 is a way to inject specific code into a base class by deriving from it and implement virtual functions and *nothing* more.

3 doesn't have anything to do with 1 and 2.

Just because all three can be used together doesn't mean they are the same.

'Cmon who wrote this article?? Rework, please.

This article really needs a rework
The example given leads to a fragile base class problem, but this is unrelated to the NVI. The same class with public virtual functions would suffer from the same problem.

To avoid the fragile base class problem, the best solution is to acknowledge the point of customization is an interface, a contract to be respected. For example: Once documented, this CAN'T CHANGE ANYMORE. Because it is part of the customization interface.
 * 1) I will always call add_impl after doing the work in add
 * 2) I will always call addAll_impl after doing the work in addAll

A better code would have provided two public interfaces non-virtual functions "add" and "addAll", and both would have called the same and unique "addEverything_impl" virtual function whose contract would be "will be called each time one needs to add items", as well as "the parameters will always this the following...".

This IS be the NVI:
 * Separation of concerns
 * One public interface for the user
 * One virtual and private (protected) interface which could be fully different from the public interface for customization purposes

As a bonus, this design would help mitigate the fragile base class problem.

Then, increase the robustness of the design by making sure the overridden "addEverything_impl" is const (if possible), and would be designed to NOT need access to "this": The function would then be a pure function, with callers giving it in/out parameters.

This is not the perfect solution, but this helps mitigate the fragile base class problem.

Paercebal (discuss • contribs) 20:48, 25 November 2014 (UTC)