[bind10-dev] Data Source class design (mixing interface and implementation)

Shane Kerr shane at isc.org
Tue Feb 2 16:20:53 UTC 2010


All,

I picked up a copy of _Effective C++_ on Saturday and read most of it on
the way home. Better than Dan Brown any day!

Anyway, as I was crossing the UK, I read "Item 34: Differentiate between
inheritance of interface and inheritance of implementation". As I
understand it, the basic point is that it is bad to have classes that
allow *implicit* default behavior. This is exactly the design for the
data source as I understand it.

So:

class DataSource {
   .
   .
   .
    virtual result getRRSigs(RRsetPtr target, const RRsetPtr rrset)
                            { return not_implemented; };
    virtual result getNSECs(RRsetPtr target, const RRsetPtr rrset)
                            { return not_implemented; };

An alternate approach would be:

class DataSource {
   .
   .
   . 
    virtual result getRRSigs(RRsetPtr target, const RRsetPtr rrset) = 0;
    virtual result getNSECs(RRsetPtr target, const RRsetPtr rrset) = 0;

// convenience function for classes that do not implement a given 
// low-level getXXX() functionality
result noGetImplemented(RRsetPtr target, const RRsetPtr rrset)
{
    return not_implemented;
}

Then a class that didn't support these would still be able to easily
support the API, but would have to choose not to implement them:

class myDataSource: DataSource {
   .
   .
   .
    // we don't support DNSSEC
    virtual result getRRSigs(RRsetPtr target, const RRsetPtr rrset) 
    { return noGetImplemented(target, rrset); }
    virtual result getNSECs(RRsetPtr target, const RRsetPtr rrset)
    { return noGetImplemented(target, rrset); }

Maybe it's more trouble than it is worth, but Item 34 convinced me!

--
Shane




More information about the bind10-dev mailing list