Newsgroups: comp.lang.smalltalk,comp.object
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!pipex!uknet!comlab.ox.ac.uk!sable.ox.ac.uk!lady0065
From: lady0065@sable.ox.ac.uk (David J Hopwood)
Subject: Always use protocols (was Re: OO to RDBMS Access)
Message-ID: <1995Jan11.021931.7422@inca.comlab.ox.ac.uk>
Sender: david.hopwood@lmh.oxford.ac.uk
Organization: Oxford University Computing Service, 13 Banbury Rd, Oxford, UK
References: <3dut9e$slo@redstone.interpath.net> <1995Jan6.184845.13171@rcmcon.com>
Date: Wed, 11 Jan 95 02:19:31 GMT
Lines: 52
Xref: glinda.oz.cs.cmu.edu comp.lang.smalltalk:19405 comp.object:24876

In article <1995Jan6.184845.13171@rcmcon.com>,
Robert Martin <rmartin@rcmcon.com> wrote:
>ron@rschultz.pdial.interpath.net writes:
>
>>Does anyone have any specific examples, frameworks, tips and
>>techniques, for  mapping objects to relational databases other than
>>the "an object = a row"  nonsense. ...
>>
>>In particular, we are looking for minimizing the degree of coupling 
>>between our domain objects and their persistence mechanisms, ...

>I use a surrogation method.  
>
>Consider that class A uses class B.   It turns out that B is
>persistent, and in an RDBMS, but I don't want A to know about the
>RDBMS.  I create an abstract version of B (B') whose methods are all pure.
>I then create two derivatives: the orignial B, and a B surrogate (Bs).

Yes, this achieves the desired effect, in a C++-like language, of hiding the
particular chosen implementation of B (persistent or not), from clients of its
interface.

The point is, though, that this is a basic part of OO which (I believe) should
be used automatically for all classes. It is essential that no client of B
should depend on its implementation, not just in this case, but in _all cases_.

Consider the situation in non-statically checked languages (eg. Smalltalk),
or in statically checked languages with structural subtyping (eg. Trellis/Owl).
In these languages, it is only the protocol of an object (ie. the set of
methods it supports, and their signatures), that determines subtyping
relations.
In effect, clients only ever rely on abstract protocols (so the
potentially disruptive change required above would never be needed).

Most (not all) of the expressive power of the languages mentioned can be
simulated in C++-like languages, by never declaring non-abstract classes (ie.
classes which do not declare all their methods as pure virtual), as the types
of method parameters, results, and instance variables.

This separates classes into two kinds: abstract protocols (sometimes referred
to as types, but this conflicts with C++ terminology), and implementation
classes. The former can only be used in declarations; the latter only to
create objects.

Without this convention, C++, Eiffel, etc., will IMHO produce inherently less
extensible programs than non-statically checked languages, or languages with
structural subtyping. They require you to have a crystal-ball knowledge of
whether a particular declaration will need to be changed to an abstract class
in the future.

David Hopwood
david.hopwood@lmh.oxford.ac.uk
