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: 109fba,7f8fc37d854731d6 X-Google-Attributes: gid109fba,public X-Google-Thread: 103376,7f8fc37d854731d6 X-Google-Attributes: gid103376,public X-Google-Thread: 1108a1,7f8fc37d854731d6 X-Google-Attributes: gid1108a1,public X-Google-Thread: 10461e,7f8fc37d854731d6 X-Google-Attributes: gid10461e,public X-Google-Thread: 114809,7f8fc37d854731d6 X-Google-Attributes: gid114809,public From: Alan Lovejoy Subject: Re: Interesting but sensitive topic to discuss (HELP: - OOP and CASE t Date: 1996/11/08 Message-ID: <3282F9EE.7E7@concentric.net> X-Deja-AN: 195247920 references: <32813322.41C6@kyebek3.kjist.ac.kr> content-type: text/plain; charset=us-ascii organization: Modulation mime-version: 1.0 newsgroups: comp.object,comp.lang.ada,comp.ai,comp.lang.c++,comp.lang.smalltalk x-mailer: Mozilla 2.01Gold (Win95; U) Date: 1996-11-08T00:00:00+00:00 List-Id: Joachim Durchholz wrote: > > alovejoy@concentric.net wrote 06.11.96: > > OO programs are systems of interacting **objects**, not systems of > > interacting **classes**. > > I think this is a bit misleading. > OO program texts are definitely systems of classes (or, rather, textual > representations of classes). In most languages that supposedly have them, "classes" exist only at compile time, not while the program runs. In any case, it is definitely the instances of the classes (the objects) whose interactions constitute the execution of a program. And in a Self program, classes never exist at all (not even in the program text). Programs are not texts. They may be **specified** by texts, but the distinction is important. The purpose of a design methodology is to help design and describe a program, not the text that specifies the program. The ideal methodology would be language independent, and the program would be derivable directly from the design without ever being expressed in a traditional programming language text. Classes are just one way to specify the behavior of an object. They are an abstraction of the common case where there are many objects all of which have the same potential behavior (I'll discuss "potential" behavior later). However, an object is a "black box." Any two objects with the identical behavior and state are functionally equivalent. How it is that there can be two different objects with the identical state and behavior makes no difference. It is an implementation detail that is intentionally hidden by the "black box" of information hiding that encapsulates an object. Perhaps the two objects were created as instances of the same class, but that is not the only possibility, nor is it required. In fact, any such requirement would essentially be a violation of the encapsulation of the object. The point here is that classes are just one possible mechanism for defining the properties of objects. The purpose of a design methodology is to design programs whose behavior meets their requirements. The textual notation used to specify the program, what language it may be written in, what the class inheritance hierarchy may be, and whether the language even has classes should be irrelevant to the methodology. Any methodology that would be helpless in the design of a program to be written in Self (which has objects but not classes) is seriously flawed. > We don't specify a single objects when > writing code for a class; instead, we specify the behaviour of a set of > objects, of which there may be none, one, or an unlimited number present > at run-time. To the extent that this is true, this is an artifact of using classes as an abstraction mechanism to specify the behavior of objects. However, it is not in general true. What a class does not do is to define the role that any of its instances will play. The role is a) the **actual** behavior of an object (that is, what messages it is sent, in which order, with what arguments, by which senders), and b) the semantics of the object, the purpose that that particular object (instance) serves in the program. Obviously, the roles of two different instances of the same class may be very different. And since a class can be used in any number of different program texts, the roles that the instances of a class may play in one program may differ substantially from the roles that instances of the class may play in some other program. A class defines the **potential** behavior and states of its instances. But just because an object can respond to a particular message does not mean it will necessarily ever be asked to do so. This is the difference between potential and actual behavior. It is central to the distinction between type and role. In order to define or specify the role that an object plays, it is essential to be able to deal with the issue of object identity. And in fact, OO languages (as opposed to OO design methodologies) typically permit the programmer to do so. It is just when the issues of object identity and the roles of specific objects become important to the design that users of the run of the mill OO design methodologies are forced to abandon the methodology and go write code. > > The architecture and design of a program is a function of what **objects** > > it contains and how they interact. > > Well, now I have to disagree. An OO program consists of classes, which are > descriptions of the behaviour of object sets. I.e. it is object behaviour > that we describe, not objects themselves (which are a bit irrelevant > anyway, we want the computer to *behave*, not to *be*). At best, the **texts** that specify a program in some programming language contain class definitions--although in some highly reflexive languages such as Smalltalk, classes are objects that exist at run time, but this is not relevant (otherwise, ALL OO languages would be required to have run-time class objects). It is true that program texts define the properties of objects, "and not the objects themselves." However, the ultimate goal of a program is the behavior of the objects, not any particular text that defines that behavior. Whether a program meets its requirements, and satisfies the person(s) who paid for it to be written, can only be determined by the behavior of the program and its objects, not by the form of the text that specifies the program. > > Class inheritance is an abstraction mechanism for code sharing. > > It is much more. It is a mechanism for specifying similarities, and in > this respect goes far beyond mere code sharing. It's true that inheritance relationships express what will be common among sets of objects. However, it is important to distinguish between the external and internal similarities among objects. One important purpose of object encapsulation is to hide the internal dissimilarities between objects, so that those objects that are externally equivalent can be used interchangeably. A class specifies the internal mechanisms of an object. Class inheritance therefore specifies the commonality of implementation mechanisms. However, it is typical that the "type" or "interface" inheritance hierarchy is different than the class (implementation) inheritance hierarchy--especially in dynamically-typed languages. This is actually what I was trying to get at in saying that "class inheritance is an abstraction mechanism for code [implementation mechanism] sharing." The type/interface hierarchy is an important topic in design, and hence is an important issue that should be addressed by a design methodology. However, while implementation inheritance is important for code reuse, change propagation and speed of development, it is at best a peripheral issue for a design methodology. Implementation inheritance should be hidden behind the "black box" of object encapsulation, at least at the design level. Why? One reason is that there are other abstraction mechanisms that can specify sharing of implementation mechanics, such as macro expansion as might be done in C, or dynamic delegation as used in the so-called prototype languages (Self, Cecil, Dylan). A design methodology should not get indigestion just because some other abstraction mechanism than class inheritance is used for this purpose. The other reason is to make the design polymorphic--that is, the design should permit any object that satisfies the required interface to be used, regardless of its internal implementation. The only place in the design where the internal implementation of a "Dictionary" should matter is in the module that specifies the design of a "Dictionary." > I can have exactly the same amount of code sharing with subroutines (that > take routines as parameters in cases where I need dynamic dispatch). This > is available in C, but nobody would regard C equivalent to an OO language! Well, that's because C doesn't have objects. And no one said that inheritance is the only way to share code. > > It has > > nothing much to do with architecture or design of a program. Proof: any > > program using class inheritance can easily be converted into a completely > > equivalent program where all the leaf classes are root classes: one simply > > duplicates all the inherited methods in each leaf class. > > On the same basis, I could declare C to be equivalent to assembler. Proof: > it is always possible to mechanically produce an equivalent assembler > program. (I won't do this :) Whether or not two languages are equivalent is not the issue. The issue is the properties of design methodologies, not the properties of languages. > The mere possibility to reproduce a program in a different way just proves > Turing equivalence, which we aren't too interested in when discussing > software engineering issues. The real issues are readability, > maintainability, and reusability of the code, by a human programmer, and > representation can have a tremendous impact on that. My argument was not that one can code two programs using different languages, algorithms, data structures, notations and object models such that both programs will have the same external inputs and outputs. I think we both agree that this can be done, but that it is irrelevant. My argument was much more specific and constrained: I was making the point that object encapsulation makes implementation inheritance irrelevant to the behavior of a program, and that therefore implementation inheritance is irrelevant to the logical design of a program as it should be expressed in a good design notation. -- Alan L. Lovejoy |==============================================| Smalltalk Consultant | Beware of Geeks bearing GIFs! | alovejoy@concentric.net |==============================================|