From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,21e68c5e7e9adc04 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: OO vs Reality: An Ada 95 Solution? Date: 1996/12/14 Message-ID: X-Deja-AN: 204135829 references: <58ue6j$b4l@nw101.infi.net> content-type: text/plain; charset=ISO-8859-1 organization: Estormza Software mime-version: 1.0 newsgroups: comp.lang.ada Date: 1996-12-14T00:00:00+00:00 List-Id: 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