[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