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=0.8 required=5.0 tests=BAYES_00,INVALID_DATE, REPLYTO_WITHOUT_TO_CC,T_FILL_THIS_FORM_SHORT autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 1108a1,66253344eaef63db X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,66253344eaef63db X-Google-Attributes: gid103376,public X-Google-Thread: 109fba,66253344eaef63db X-Google-Attributes: gid109fba,public X-Google-ArrivalTime: 1994-09-30 16:36:46 PST Path: bga.com!news.sprintlink.net!howland.reston.ans.net!swiss.ans.net!newsgate.watson.ibm.com!watnews.watson.ibm.com!ncohen From: ncohen@watson.ibm.com (Norman H. Cohen) Newsgroups: comp.lang.ada,comp.object,comp.lang.c++ Subject: Re: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Date: 30 Sep 1994 20:27:49 GMT Organization: IBM T.J. Watson Research Center Distribution: world Message-ID: <36hsc5$g1q@watnews1.watson.ibm.com> References: <1994Sep27.165203.9192@swlvx2.msd.ray.com> <36bt0c$17oo@watnews1.watson.ibm.com> <1994Sep29.103358@di.epfl.ch> <1994Sep29.133526.2134@swlvx2.msd.ray.com> Reply-To: ncohen@watson.ibm.com NNTP-Posting-Host: rios8.watson.ibm.com Keywords: Ada 9X, C++, object-oriented Xref: bga.com comp.lang.ada:6344 comp.object:6935 comp.lang.c++:31146 Date: 1994-09-30T20:27:49+00:00 List-Id: In article <1994Sep29.133526.2134@swlvx2.msd.ray.com>, jgv@swl.msd.ray.com (John Volan) writes: |> Not true. The premise of my original question was that the binary association |> between Employee and Office is a public feature fully visible to their |> clients -- and they could even include each other as clients! Maybe the |> *implementation* of this binary association is strictly internal to the |> abstraction (I agree that it should be), but the *existence* of this binary |> association should be a visible part of this abstraction. In other words, |> the interface to the Employee class should include some subprogram(s) that |> allow(s) a client to fetch the identity of (a pointer to) the associated Office. |> Likewise the interface to the Office class should include some subprogram(s) |> that allow(s) a client to fetch the identity of (a pointer to) the associated |> Employee. And the interface to both classes should include some subprogram(s) |> that allow a client to establish an association between a given Office and a |> given Employee, in such a way as to always guarantee the following invariant |> assertion: |> |> For any given Employee "E" and Office "O", |> E occupies O if and only if O is occupied by E. ... |> Unfortunately, hiding the pointer types within the private part of the parent |> prevents them from being visible to clients, even via child packages. This |> defeats the whole purpose of having a mutually recursive *abstraction* -- |> that is, something that provides an *interface* to some useful services while |> encapsulating the *implementation* of those services. The five lines just above seem to contradict your earlier statement that the pointer types (the imnplementation of the binary association between offices and employees) should be private, so I'll assume you really meant what you said the first time and not the second time. Pasting together bits and pieces of solutions proposed by Mark Biggar, Magnus Kempe, and me, isn't the following all that you're really looking for? package Employees_And_Offices is type Employee_Parent is abstract tagged private; type Employee_Pointer is access Employee_Parent'Class; type Office_Parent is abstract tagged private; type Office_Pointer is access Office_Parent'Class; -- Nondispatching operations concerned with the relationship -- between offices and employees: function Office_Occupied_By (The_Employee: Employee_Parent'Class) return Office_Pointer; function Employee_Occupying (The_Office: in Office_Parent'Class) return Employee_Pointer; procedure Occupy (The_Employee : in Employee_Pointer; The_Office : in Office_Pointer); private type Employee_Parent is tagged record Its_Occupied_Office: Office_Pointer; end record; type Office_Parent is tagged record Its_Occupying_Employee: Employee_Pointer; end record; end Employees_And_Offices; package Employees_And_Offices.Employees is type Employee is new Employee_Parent with private; [Operations concerned with the Employee "other stuff"] private type Employee is new Employee_Parent with record [the other stuff] end record; end Employees_And_Offices.Employees; package Employees_And_Offices.Offices is type Office is new Office_Parent with private; [Operations concerned with the Office "other stuff"] private type Office is new Office_Parent with record [the other stuff] end record; end Employees_And_Offices.Offices; Employee and Office can each see the other's links to itself, but each type's "other stuff" is hidden from the other. Outside clients can't even see the links, just the subprograms for manipulating the links. -- Norman H. Cohen ncohen@watson.ibm.com