[Exceptional C++ Style] Item 18 - Virtuality
Kevlin Henney
kevlin at curbralan.com
Fri Jan 7 02:58:04 EST 2005
In message <31d4d63b05010606048abbf40 at mail.gmail.com>, Timothy Wright
<tcw321 at gmail.com> writes
> My designs that tend to be
>large and couple many classes give me the biggest problems in the long
>run, they smell. So I am always looking for best practices like NVI
>to use, bits of knowledge so I don't have to learn by painful
>experience. But, as people pointed out, NVI has problems too.
NVI will not help you with such partitioning. The problem is that the
classes are large and coupled. Techniques that further divide and
decouple are what you need, eg the use of call-out interfaces to break
cyclic dependencies.
>Ultimately, I find out what smells and what does not by experience and
>I have not found (maybe it can't exist) a good design book that gives
>me more ideas on what is good and what is bad. Design Pattern and
>refactoring books seem to come closest. The problem with the advice
>"keep it simple but not too simple" is that it does not answer
>specific questions.
Indeed. This is why a rich vocabulary of techniques is needed when
considering any design. Few potted solutions exist out of the box.
>Is NVI good?
For most definitions of "good", no it isn't. If you consider NVI a
design smell, you will not go too far wrong.
>Should I use the pimpl design
>(another Herb's suggestions) everywhere?
Definitely not. And I don't think that Herb suggests using it
everywhere. It is technique that can be applied to great effect on
certain (not all) classes in your system to isolate build and binary
dependencies. Any concrete class whose internal structure is subject to
frequent change, but attracts many users and a long build time, is a
potential candidate. Another technique is to introduce an interface
class, which is particularly suitable at the base of a class hierarchy.
You can even combine the two approaches for concrete implementations in
a class hierarchy that still attract too many dependencies. Likewise,
other techniques such as using unnamed namespaces to isolate
implementation specifics within .cpp files can also help. All of these
techniques play the role of minimising the footprint of an
implementation in the header.
>What is simple and what adds
>too much complication? Keeping member variables private is considered
>a good idea but does add complexity but everyone feels that it is a
>good price to pay.
It does rather depend on what is meant by "complexity". To reiterate a
point I made before, encapsulation is an abstraction process that has
the effect of simplifying class usage and class evolution. It is easy to
find examples that benefit from hiding data representation almost the
moment you think about it -- in fact, there are so many, you end up
tripping over them! There is plenty of evidence concerning the benefits
of such encapsulation, and plenty of evidence that its absence is more
often a problem than a solution -- simplistic rather than simple.
>I guess that is why ACCU and these discussion groups exist. :-)
Indeed :-)
Kevlin
--
____________________________________________________________
Kevlin Henney phone: +44 117 942 2990
mailto:kevlin at curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________
More information about the Effective-cpp
mailing list