Print

Print


At 10:22 AM 4/15/98 -0700, Al Christians wrote:
>I think that the Demeter proponents are aware of this and recognize
>that the interfaces can wind up with many trivial and non-essential
>functions pushed back into the supplier package to spare the client
>the complications of navigating and interpreting supplied data types.

    This is why software engineering is an art as well as a science.
Failure to provide a necessary interface to an abstraction will complicate
the job and code of the user of the abstraction.  Providing unnecessary
interfaces makes your job as the implementor of the abstraction harder, and
makes understanding the interface harder for everyone.  Breaking the
abstraction to allow user access to the components is almost always wrong.

     (Hmmm, flame avoidance, it is natural for the interface to provide
functions which due to good design map directly onto the underlying
implementation:

      function Author (M: in Message) return String is
      begin return M.Author; end Author;

      But that is not breaking the abstraction.  The abstract type could be
implemented differently and the details hidden by the abstraction:

      function Author (M: in Message) return String is
      begin return M.Author.Text(1..M.Author.Length); end Author;

      Breaking the abstraction involves providing access to details which
are not part of the abstraction in a way that requires that those details
be included in the representation.  Worst case is making visible the exact
details of the entire implementation--forgetting to make the type private.
End digression.)

      Juggling the conflicting requirements in a way that results in the
overall program being as uncomplex as possible is the art and engineering
of software engineering.  Easy it ain't.

>In Ada, wouldn't we want to move these non-essential functions into
>child packages of the supplier package, where each child package
>implements some coherent or cohesive bundle of optional features?

    What you are really doing is creating a set of views of an abstraction,
where the parent package is the most abstract, and the various child
packages decorate that view in various ways.  The fact that you don't have
different derived types (subtypes in OO-talk) in the child packages
shouldn't obscure this view.  In fact, I would rather provide the same
operation in two or more children than to "accidently" require accessing
the wrong view.  (Since you have a full tree, you could move such an
operation to a common parent, but sometimes there are operations that
belong in unrelated children but not in the parent.)

>I suppose it's not cheating to not count the references from the child to
>the parent as a level of indirection according to the rule of Demeter
>-- his should be an improvement of the design, because the indirection has
>to be hierarchically organized.

    Stated that way, I think I agree.  But translating the Rule of Demeter
into forbidding access to functions in both grandchild and its grandparent
may be too restrictive.  On the other hand access to both a child and an
unrelated grandchild (uncle and nephew?) looks very suspicious no matter
how you word it.

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...