Xref: utzoo comp.lang.eiffel:1402 comp.object:2549 Path: utzoo!mnetor!tmsoft!torsqnt!lethe!yunexus!ists!helios.physics.utoronto.ca!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!olivea!uunet!mcsun!ukc!pyrltd!tetrauk!rick From: rick@tetrauk.UUCP (Rick Jones) Newsgroups: comp.lang.eiffel,comp.object Subject: Granularity (was: Inheritance and Information Hiding) Message-ID: <1087@tetrauk.UUCP> Date: 7 Feb 91 18:29:26 GMT References: <10612@pasteur.Berkeley.EDU> <485@eiffel.UUCP> <488@eiffel.UUCP> <1991Feb1.015749.10111@Neon.Stanford.EDU> <1081@tetrauk.UUCP> <821@puck.mrcu> <1991Feb6.045542.791@visix.com> Reply-To: rick@tetrauk.UUCP (Rick Jones) Organization: Tetra Ltd., Maidenhead, UK Lines: 137 In a previous article I raised the issue of mutable v. immutable objects; I'm glad I did, it has provoked some very interesting responses: In article <1991Feb3.225619.29491@Neon.Stanford.EDU> craig@Neon.Stanford.EDU (Craig D. Chambers) writes: >I described this situation in a posting to comp.object a while back. I had an inkling I'd seen or heard something on these lines before - it must have been your article. Are you proposing an arbitrary number of programmer-defined sub-interfaces? Although this would be flexible, I can see that it could lead to greater complications and ultimately make the design process even more complex. >I'm concerned a bit about achieving the desired syntactic conciseness; >"read-only array" is a lot longer than "array". I agree - as above, I think there is a danger of what starts as an enhancement eventually leading to unreadable code. >Maybe the compiler could somehow infer the right subinterface. If you look at it carefully, this is really what Bertrand Meyer's global checking is intended to achieve. The *effective* sub-interface depends on the context in which the object reference is used. >Of course, subinterfaces aren't strictly required, since each >subinterface could just be a separate type/class. See below - you're on the same track as Paul Johnson >This sounds like you're proposing a built-in read-only subinterface >much like const in C++. This was my initial idea, but I'm not sure that it really addresses the problem properly. Continuing with the example of figures (I sometimes wonder to what extent these things reflect reality, but at least we all understand what is meant), then you can have an operation "scale" applicable to any figure, which will not change its shape or properties, only its size. You may well want a scaleable square, but you still can't allow it to have either its number of vertices changed, nor its aspect ratio. In article <821@puck.mrcu> paj@uk.co.gec-mrc (Paul Johnson) writes: > >Yes. I have been thinking along precisely these lines and have come >up with some ideas which I call "Fine Grain Inheritance". >I believe you should split your class up into lots and lots of little >superclasses, each implementing one elementary concept (such as "first >item" or "read/write current item") and usually having only one or two >attributes. I have also wondered whether this is a possible solution. My fear is that you might end up having to resolve awkward clashes in a complex class which inherits from very many smaller classes. I haven't been able to try it in practice, so that is just a gut reaction. >This scheme becomes completely flexible when a new type rule (which I >call the "Sibling-Supertype" rule) is added which (put briefly) allows >the following. > If the supertypes of A are a subset of the supertypes of B, then A > is a supertype of B. This I like. It appears a clean way of separating the type hierarchy from the class hierarchy, which I believe is ultimately at the bottom of this problem. >The only problem comes when coarse grain libraries must be reused as well. They would still be compatible, just not as reusable as the fine grain stuff. >Of course, tools like "flat" and "short" become absolutely vital in >fine grain libraries, as does multiple inheritance. Makes a convincing argument for MI :-) (but see below) >See you all at TOOLS '91. I look forward to meeting you - I'd like to discuss this further. In article <1991Feb6.045542.791@visix.com> adam@visix.com (Adam Kao) writes: >I have always felt uncomfortable with the emphasis on "Class" in >languages like Smalltalk, C++ etc. To me, the notion of an Object >seems much more basic and fundamental than a Class. > [...] >In the real world, objects do not, strictly speaking, belong to a >class. A classification system is imposed on real objects by our >world view; class membership is an answer to a question we phrase. >Different question, different answer. My current development project has lead to an interesting situation, which is related both to this topic, and to the question of granularity discussed above. Briefly, we are building OLTP server processes, and decided to use an OO approach so we treated the servers as "classes" when defining their interfaces. This is a clean way of giving a behavioural view of the online stored data. I envisaged writing these servers as Eiffel classes, with the features available as services callable by a client. Mainly for implementation reasons this proved impractical, and the final structure is that each "feature" of the server is in fact written as a separate language "class". The result is that the server "object-interface" is a composite construction, where each "feature" is a separate component. A new server can be assembled using several already exisiting "features", plus new special ones where relevant. In this "macro-object" (it is an object - information hiding, interface defined by behaviour, etc), reuse is by assembly, not inheritance. Of course the smaller components are being written in an object oriented language, but at a different level. It seems that maybe the idea of defining an object interface at the language level by assembling a shopping list of features (Bertrand Meyer talks about this in OOSC), *but where each feature is a separate module*, is a possible alternative to inheritance for reuse. This seems to be very close to Paul Johnson's fine grain inheritance, but is inheritance really the correct mechanism, or does it just look right because it's there? I'm a bit too much up to my ears in the project at the moment to think properly about the wider implications, but it does seem to address the issues of finer granularity, and also the notion of type could be defined in terms of the set, or subset, of features assembled for any particular object. I am coming more and more to believe that finer granularity is an important issue when it comes to effective reuse. The larger a traditional class, the more complex it is, and the less likely it is to be reusable. But reuse by inheritance by definition adds to the parent class, thus creating ever larger classes. It is almost self-defeating. I'm not saying inheritance isn't valuable, but perhaps we need something else as well. Food for thought? -- Rick Jones Tetra Ltd. Maidenhead, Your .signature has expired, Berks, UK please apply to your analyst for a replacement rick@tetrauk.uucp