comp.lang.ada
 help / color / mirror / Atom feed
From: jgv@swl.msd.ray.com (John Volan)
Subject: Re: Decoupled Mutual Recursion Challenger
Date: Tue, 11 Oct 1994 23:34:03 GMT
Date: 1994-10-11T23:34:03+00:00	[thread overview]
Message-ID: <1994Oct11.233403.25558@swlvx2.msd.ray.com> (raw)
In-Reply-To: 1994Oct11.122356@di.epfl.ch

Robb.Nebbe@di.epfl.ch (Robb Nebbe) writes:

>|> I should point out that, in any object-oriented application,
>|> responsibility for *many* aspects of the system's functionality winds
>|> up being distributed across *many* classes of objects.

>This is the way it should be. However, you are suggesting that a single
>aspect of the system's functionality be distributed accrossed multiple
>packages, which isn't the same thing.

I am indeed suggesting that a *single* aspect of system functionality
can be, and often should be, distributed across multiple classes (and
therefore, packages).  That's what I thought I said in the quote
above, but obviously, my phrasing wasn't very clear.  Let me rephrase:
It's *often* the case that if you take any *particular* *single*
"functionality" of an object-oriented system, you might *not* find that
functionality totally encapsulated within any *one* object class.
Instead, that functionality may actually be manifested as a multitude
of similar methods scattered over many different classes of objects.
Each of these methods only deals with that "functionality" directly in
terms of its own particular object class, and that is as it should be.
However, there may very well be *collaborations* among these methods:
Any one of these methods, in any one of these classes, may wind up
calling the corresponding methods in one or more of the other classes,
and these may wind up propagating related calls to yet other classes,
and so on.  But the "algorithm" for that overall system functionality
never appears completely in one place.  The only way to visualize the
"algorithm" is to trace the collaborative propagation of method calls
across the various classes.

That, I think, is the difference between functionally-designed systems
and systems designed in an object-oriented fashion.  In a
functionally-designed system, you may very well see a major system
functionality manifested as a single module of code.  The algorithm
can be found all in one place, but it winds up touching many different
types of data.  Other functional modules may wind up touching all of
the same data types.  So if you ask the question "What code affects
this one particular data *type*?" you will not be able to find the
answer encapsulated in any one place.  You wind up having to search
through all the functional modules.

On the other hand, in an object-oriented system, we make the data
types (i.e., the object classes) central, and the functions become
secondary.  Any one class of object may participate in many different
areas of system functionality, to its own extent.  But those same
functional areas might also be dealt with partly within many other
object classes as well.  So if you ask the question "What code affects
this one particular data *type*?" the answer is simple: the methods in
this class.  But if you ask the question "What code implements this
particular *functionality*?" you wind up having to search through
many object classes to find it all.

As I said before, this difficulty in "seeing" overall functionality
within an object-oriented system is only a symptom of *code*.
Object-oriented *analysis* and *design* techniques have the liberty of
presenting multiple complementary views to show different aspects of a
developing object-oriented system.  These views can include
functionally-oriented "cuts" at the design, where you can focus on
just those object classes, and just those methods of those classes,
that pertain to a given functionality.  That way, you can get a sense
of the overall "algorithm" implemented by these disparate methods, by
seeing their pattern of propagation.  But just because you provide
such a view during analysis or design, does *not* suggest that your
final implementation must have a functionally-oriented module that
totally encapsulates all of those methods in one place.

>Your solution seems to contradict itself. You want to put the
>abstractions in separate packages which suggests loose coupling but
>you want them to include pointers to each other which suggests tight
>coupling. You seem to be sitting on the fence trying to decide which
>side you want to be on.

Face it: 

OBJECT CLASSES WILL BE COUPLED TO EACH OTHER TO THE EXTENT THAT THEY
SHARE RESPONSIBILITIES FOR OVERALL FUNCTIONALITIES OF THE SYSTEM.

This coupling is everywhere. But how *deep* must this coupling be? Can
we limit the coupling to having one separately-encapsulated module
make calls to other related, yet still separately-encapsulated,
modules?  Or do we wind up having to encapsulate all classes within a
single module, every time we find some functionality that they share
responsibility for?

>In article <1994Oct7.222716.8690@swlvx2.msd.ray.com>, jgv@swl.msd.ray.com (John Volan) writes:
>|> C'mon, Robb, you are totally misunderstanding me.  I am not claiming
>|> that "my" implementation is the "best" one possible.  I'm just claiming
>|> that is one *possible* implementation.

>... and for which you have seen good solutions but which don't
>satisfy your constraints. I'm not claiming that there is no advantages
>to implementing the relation with two pointers; I'm claiming that to
>do that in two completely separate packages doesn't provide you with
>any advantages.

>If you want to implement a realtionship with pointers put the two
>abstractions in the same package or in the same hierarchy of packages.
>If you want to put them in completely separate packages then use an
>ADT to handle the relationship.

The issue of associations is only a particularly poignant special case
of this overall issue of "functional coupling between object classes".
You claim that I have only two choices for any association: (1) Have
the two classes relinquish all responsibility over that association
and give it to a third party, just so that the association can be
encapsulated in one place; or (2) Let the two classes take on mutual
responsibility for the association, but only if the two classes are
encapsulated together as a single module, just so that the association
can be encapsulated all in one place.  The first choice means that
we're giving up object-oriented encapsulation: It is no longer
possible to say that all the code that relates *directly* to one
particular class of object can be found encapsulated within the
methods of that class -- you have to hunt through all the association
modules, too.  The second choice also gives up on object-oriented
encapsulation: Object classes no longer act as the units of
modularity/encapsulation/separate compilation at all!

Two choices, both giving up on object-oriented encapsulation -- that's
it, take it or leave it?  I don't buy that.  I think there is a third
alternative: Distribute the responsibility -- we'll live with that --
but still keep the classes separately encapsulated.

I say again: It *can* be done. True, it's not *built in* to Ada9X.
But Ada (even Ada 83) has always had certain facilities for
*extending* the language beyond its *built in* capabilities.
That should be suggestive.

If any of you folks out there think they have a solution -- in
particular, if anyone thinks that exploiting inheritance is the answer
-- then I challenge you to take the acid test: Show that your solution
can handle even the situation of one class in a mutually-recursive
association with one of its own subclasses.  I fully intend to
demonstrate that my own solution can satisfy this test ... but I
don't want to spoil it for those of you who enjoy a challenge ... :-)

-- John Volan

--------------------------------------------------------------------------------
--  Me : Person := (Name                => "John Volan",
--                  Company             => "Raytheon Missile Systems Division",
--                  E_Mail_Address      => "jgv@swl.msd.ray.com",
--                  Affiliation         => "Enthusiastic member of Team Ada!",
--                  Humorous_Disclaimer => "These opinions are undefined " &
--                                         "by my employer and therefore " &
--                                         "any use of them would be "     &
--                                         "totally erroneous.");
--------------------------------------------------------------------------------






      parent reply	other threads:[~1994-10-11 23:34 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1994Oct7.130100.26953@swlvx2.msd.ray.com>
1994-10-11 13:58 ` Decoupled Mutual Recursion Challenger [Was: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG)] Norman H. Cohen
1994-10-12 13:17   ` Decoupled Mutual Recursion Challenger John Volan
     [not found] ` <1994Oct7.165517@di.epfl.ch>
     [not found]   ` <1994Oct7.222716.8690@swlvx2.msd.ray.com>
     [not found]     ` <1994Oct11.122356@di.epfl.ch>
1994-10-11 23:34       ` John Volan [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox