comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: OO vs Reality:  An Ada 95 Solution?
Date: 1996/12/14
Date: 1996-12-14T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023280001412961146310001@news.ni.net> (raw)
In-Reply-To: 58ue6j$b4l@nw101.infi.net


In article <58ue6j$b4l@nw101.infi.net>, mcriley@bix.com (Marc A. Criley) wrote:

>The problem arises when some small bit of information about this class is
>needed by another, such as the values a particular attribute may hold.  The
>entire class in which those values are defined gets dragged along with that
>type definition.  One might argue that smart compilers/linkers/code
>strippers can remove the unnecessary code, but I feel that misses the
>point.  Why should all the operations be brought in when all that's needed
>is (for instance) an index range?
>
>The needed attribute type definition could be pulled out of the class and
>placed in a (gasp!) common types package, but where does that end?
>Eventually most of the types get migrated to such packages, with only
>attribute declarations and operations remaining in the now not-so-cohesive
>class package.

There's nothing wrong with common types packages, as long as you do it
correctly.  Most shops get it wrong by putting every type in the system in
a  Common_Types package, and the result is a compilation nightmare.

Like any system, you must minimize the dependencies among the subsystems. 
In an Ada program, this is the same as saying you must minimize the
compilation dependencies among the modules.

The key is that a types package should have a collection of "cohesive"
types, ie they are strongly related to each other.  Common types packages
are OK, just have a few of them (not just 1, that would be huge mistake)
with each having a few highly cohesive types.

I'll define what it means to be cohesive below.

The solution for you is to have a common types package that contains the
single type you need, and this types package gets with'd by the 2 packages
that need it (and those are the only 2 that with it).  For example,

package ADT_Types is

   type Index_Range is 1 .. 10;  -- say

end;  

Here's client number 1:

with ADT_Types;
package ADT_Package is

   type T is tagged private;

   procedure P (O : T);
...
private 
   
   type A is array (ADT_Types.Index_Range) of ...;
   type T is
      record
         O : A;
         ...
      end record;

end ADT_Package;

And here's client number 2:

with ADT_Types;
package Some_Other_Package is

   ... -- uses type ADT_Types.Index_Range somehow
end;

Time and time again I see shops that have, say, 1 common types package,
shared by all the modules in the system.  Big, big mistake.  Have a few
common types packages (where necessary), each one shared by only a few of
the modules in the system.

A good example of a cohesive module is the standard Ada 95 package
Interfaces.  It contains declarations of interface types (such as
Unsigned_16, etc) and nothing else.

Of course, there's nothing wrong with just putting the type in the
ADT_Package, and having the client with that package to get at the type. 
If you don't use any other resources exported from that package (and if
you're using an incremental compiler) then you shouldn't be affected by any
changes.

You do bring up an interesting point, though, which relates to module
design.   Thinking about how to properly organize the modules (packages) is
every bit as important as the class design in an (object-oriented) system. 
Most of the books out there nowadays discuss class design, but give module
design short shrift.  So it's no real surprise that many Ada programmers
get it wrong.

I have a friend who favors C.  His comment about us was that "You can
always tell who the Ada programmers are - they're the ones reading a
newspaper at their terminal."  He was refering to the fact that many Ada
programmers often have to wait a long, long time for the compile to finish.

But there's no need for that!  The problem is that most Ada programmers
don't understand module design, and aren't aware of the techniques to
minimize module coupling.  (Actually, most programmers don't even know what
"coupling" and "cohesion" are.)

Something Booch recognized early on was that to implement an abstraction
often requires more than a just a single class or package.  My own
experiance confirms this.

There'll be a small group of Ada packages that are "highly cohesive,"
working together to implement an abstraction.  Spreading the work out this
way prevents you from having a single but huge package to do the work.

The designers of Ada 95 recognized this idiom and added language support
for a "subsystem," defined as a collection of child library units that
share a common library unit root.  For the implementation of a complex
abstraction, typically one package serves as the interface to the rest of
the world, and the other (private) packages serve as the "body" of the
abstraction.

This group of packages that implement a complex abstraction typically share
some common types.  So just put the types in a "common types" package that
gets with'd by - and only by - the packages in the subsystem.

That's the answer to your question "Where does putting types in a common
types package stop?"  The type you're interested in gets put in the types
package for *this* subsystem. And other subsytems can have their own
common-to-the-subsystem types package.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
mheaney@ni.net
(818) 985-1271




      reply	other threads:[~1996-12-14  0:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-12-14  0:00 OO vs Reality: An Ada 95 Solution? Marc A. Criley
1996-12-14  0:00 ` Matthew Heaney [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