[Qt-interest] Non-Virtual Interface Idiom
Herb Sutter
herb.sutter at gmail.com
Tue Dec 21 02:48:45 CET 2010
<Oliver.Knoll <at> comit.ch> writes:
> On 2010-12-19 Piotr Piotr Dobrogost wrote:
>
> > One of design rules made popular by Herb Sutter is Non-Virtual Interface
Idiom
> > explained in the article "Virtuality" in C/C++ Users Journal, 19(9),
September 2001
> > (http://www.gotw.ca/publications/mill18.htm), which can be summarized in
the
> > guideline "Prefer to make interfaces nonvirtual, using Template Method."
BTW, I subsequently tightened up the wording a little on this to emphasize
that this is different from the Template Method pattern. The current advice
can be found in C++ Coding Standards Item 39, "Consider making virtual
functions nonpublic, and public functions nonvirtual."
> I think Herb Sutter did not understand the point of interfaces: he mixes
implementation with interfaces.
> When I talk about "interfaces" I think "Java interfaces", and in C++ that
renders to pure virtual classes
> (in my understanding of "interfaces").
First, the above was said to a C++ audience, and "interface" was used in the
sense of "the public interface of a class" (i.e., not of a Java- or C#-style
interface).
A Java/C#-style interface is its own thing, and of course it naturally
consists of only what in C++ are called pure virtual functions. (Aside: Note
that Java/C# interface methods are subtly different from virtual methods even
in those languages. Briefly, interface methods should be thought of as being
implemented, whereas virtual methods are overridden, and there is a
difference. People often don't grok that distinction at first.)
> But for interfaces this totally does not make sense to me,
Right, it's about classes. That classes can choose to implement NVI is a
significant advantage of classes over interfaces. However, in those
environments you have to stick with interfaces most of the time because of the
SI restriction.
> and the fact that this practise has had no impact
> since 2001 (the time this article was published) tells me that others
agree ;)
I don't know how much impact the article itself had, but NVI has been
independently rediscovered lots of times (including long before my article),
and is followed assiduously in lots of popular frameworks including the C++
standard library (which has only one public virtual function, exception::what)
and the .NET Frameworks (see http://tinyurl.com/22ksqxp) which includes
explicit advice to make virtual methods protected rather than public (private
is not an option in .NET) -- the advice is sound and applies perfectly well,
and of course it applies to _classes_ rather than to interfaces.
It's just good engineering to decouple two separate and independent things:
(a) the interface presented to the outside world (callers)
(b) the customization hooks presented to derived classes (implementers)
because they are different audiences with different needs. A base class
provides both of them, and they are usually best decoupled (and people
continue to rediscover).
Interfaces don't allow you to decouple them, and interfaces are best thought
of as specifying base class public methods. That is, in Java and C#, it's good
design to consider implementing interface methods using public _nonvirtual_
(sealed/final) methods in the class that delegate to new nonpublic virtual
methods.
Herb
More information about the Qt-interest-old
mailing list