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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,8ff80a74f45b5cd3 X-Google-Attributes: gidfac41,public X-Google-Thread: 103376,8ff80a74f45b5cd3 X-Google-Attributes: gid103376,public From: doylep@ecf.toronto.edu (Patrick Doyle) Subject: Re: Visibility and access to "public" attributes Date: 1997/08/30 Message-ID: #1/1 X-Deja-AN: 269027228 X-Nntp-Posting-Host: skule.ecf Sender: news@ecf.toronto.edu (News Administrator) References: <872885107.17682@dejanews.com> Organization: University of Toronto, Engineering Computing Facility Newsgroups: comp.lang.ada,comp.lang.eiffel Date: 1997-08-30T00:00:00+00:00 List-Id: In article <872885107.17682@dejanews.com>, wrote: >In my original post on this subject, I wrote: > >>That said, I think it is fair to say that I believe the idea behind >>Ada's "all or nothing" approach is that you may want to ensure that >>a client never depends on some of a type's attributes. For instance, >>you might have an Aircraft class with a Take_Off method. Should a >>client be able to view (and thus potentially depend upon) attributes >>in the Aircraft type that might change but would not impact the >>interface to Take_Off? > >To which Patrick Doyle replied: > >>If the attributes change, then what used to be an attribute >>can be changed into a function with absolutely no effect on >>client code. (And, if it turns out to be impossible to do >>this, then you have a problem on your hands even in Ada.) >>The Eiffel approach is *no different* from using accessors. > >The issue I'm raising here is the ability of a client to >depend on a class' attribute (feature). To expand on the >Aircraft example a bit (pardon my Eiffel- I don't write the >langauge fluenty; I'm just a tourist! ;) ) > >class AIRCRAFT > Take_Off; -- I don't know how you write methods in Eiffel! >feature > > Propeller_RPM: Integer; > >end Just to clarify, I think you mean this... class AIRCRAFT feature {ANY} take_off is do ... end Propeller_RPM : INTEGER; end >Now, suppose you change the AIRCRAFT class to have jet engines and >thus remove or change the Propeller_RPM attribute? Because it was >*visible*, someone may have written code to read it and now if you >change the spec of the class their code will break. It doesn't >matter that they can't update the attribute! If they can refer to it >at all and you remove the attribute from the class definition, their >code is broken! In this case, the only way to avoid breaking client >code written for the original definition of AIRCRAFT would be to >add a useless Propeller_RPM accessor that returns zero or something. There are two possiblities here: 1. You shouldn't have made Propeller_RPM visible in the first place. The class should have looked like this: class AIRCRAFT feature {ANY} take_off is do ... end feature {NONE} propeller_RPM : INTEGER end 2. If you made propeller_RPM visible, and now it no longer applies, then sorry, but your design has changed and you're going to need to rewrite some classes. No language I know of will help here. I think the issue here is that you don't *have to* make attributes visible. >In this case, the AIRCRAFT class' features/attributes would have been >better off hidden, since the Take_Off method's interface didn't >change when the Propeller_RPM attribute was changed/removed. Indeed. >Now to Pat's question: > >>What I'd like to know is, how do you decide in Ada whether >>to make an attribute public, and thus irrevocably commit to >>allowing clients to assign to it? > >Personally, I only do this for types which cannot be put in an >invalid state by the client setting the attributes, e.g. > > [Example] > >Here, the 1D_Point and 2D_Point classes cannot be put into >inconsistent/invalid states as a result of the client setting >the X and Y coordinates. The distance between them can always >be computed (within arithmetic range of machine, of course). > >Now, if I had a type with more complex methods >and it was possible for a user-adjusted attribute to put the >object into an inconsistent state, then I would make its >attributes private and the attributes would be set only by >higher-level methods. That is, I wouldn't provide a low-level >accessor to set an attribute if doing so could allow the object >to be put into an invalid state. That's interesting, but the trouble is that a class can't possibly know what's an invalid state for every conceivable object of that class. What I'm trying to say is that subclasses might have constraints on the values of these attributes, and the superclass can't be expected to know that in advance. So if you expect people to subclass (or even if you don't expect them to!), then you should never allow clients to directly assign values to attributes. Eiffel's syntax prevents people from making attributes writeable, which IMHO is not a great loss. It just keeps us from being lazy and adding the appropriate encapsulating code. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca