Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!pt.cs.cmu.edu!sei!ajpo!eberard From: eberard@ajpo.sei.cmu.edu (Edward Berard) Newsgroups: comp.lang.c++ Subject: Re: Objectifying incoming messages? Summary: There are some interesting issues here... Keywords: Messages Message-ID: <533@ajpo.sei.cmu.edu> Date: 3 Aug 89 15:40:39 GMT References: <444@cimshop.UUCP> <452@cimshop.UUCP> Lines: 148 In article <452@cimshop.UUCP>, davidm@cimshop.UUCP (David Masterson) writes: > In a previous message, > > I talked about the mechanics of changing general messages into specific > objects in order to turn a bit-stream (say, from a network) into a known > object. Most seem to feel that it is the responsibility of an object to > write itself out and read itself back in (construct itself). Obviously, the > message processor (disk reader) has to get clues from the bit-stream as to > what type of object is coming in and, therefore, switch to the appropriate > object construction mechanism. The problem is that this leads to > inefficiencies... [stuff deleted] > There are other potential problems as well, in particular the probability of undesirable object coupling. Before I define "object coupling," I must first define the concept of "primitive" objects and classes. A primitive object or class is one which is furnished by the environment, e.g., an object or class which is defined in the definition of the programming language. Primitive objects and classes have two main uses: the construction of non-primitive (i.e., user-defined) objects and classes, and a means of low-level communication among objects, and with the outside world. Object coupling occurs when a class refers to some _specific_ non-primitive object which is an instance of a class other than itself, or to some _specific_, _different_ non-primitive class. There are two types of object coupling: white-box object coupling and black-box object coupling. Black-box object coupling occurs when the class treats the specific, different class as a black box, i.e., it makes no direct references to the state of the class, or to the states of objects which are instances of the class. For example, consider a "list of names" class. Assume that this class is treated like any other list, e.g., one can add names to the list, delete names from the list, and ask how many names are contained in the list. However, there are no specific references to the state of an item contained in the list (i.e., a name). Assuming that this class refers to a specific "name" class, and that the "list of names" class was derived from a more generic "list class," then we say that the "list of names" class black-box couples the list class with the name class. White-box coupling occurs when a class makes specific references to the state of an object which is an instance of a specific different class, or takes explicit advantage of the knowledge of the underlying implementation of a different class. For example, using the "list of names" class from the above example, suppose that we required that the list be an ordered list. If we accomplished this by, for example, letting the list class know that the underlying implementation of a name object was an ASCII string, then the original list class is now white-box coupled with the name class. The most common examples of white-box coupling are when people place input and output operations in the interface to a class. For example, consider a counter class, i.e., instances of this class are used to retain counts of some phenomenon. Suppose the operations in the interface for the counter class are: zero (the counter), increment (the value of the counter by one), decrement (the value of the counter by one), and display (the value of the counter). Concerning the "dislay" operation: the question is "display the value of the counter _where_?" Because the "display" operation is required to change the state of an object which is not an instance of the counter class (i.e., it must change the state of some "output object") we say that the counter object is white-box coupled with the "output object." Object coupling has two undesirable side effects: - It reduces the reusability of objects and classes. For example, suppose another application required a counter class, but did not require the specific output object to which the above counter class was coupled. A generic list class, for example, can be combined with many other classes. - It reduces the reliability of systems which contain coupled objects by providing a mechanism for "ripple effects," i.e., it allows for a change in one part of a system to potentially result in unwanted erroneous changes in other parts of the same system. For example, suppose the operations in the interface to the output object change. Then all the methods in other classes which make specific reference to these operations may potentially have to be changed. Please note that object coupling is necessary for object-oriented applications to accomplish work. What we want to avoid is unnecessary object coupling. This brings up a number of systems questions, e.g., when should objects be coupled, and what collections of coupled objects (i.e., systems of objects) are both highly reusable, and reasonably reliable? [By the way, there are specific techniques for removing undesirable object coupling. There are also specific guidelines for both avoiding unnecessary object coupling, and in the construction of reusable systems of objects.] > Perhaps, there is a need to define what types of data are capable of > being written out of a program and (by implication) what types of data can be > read into a program. Since an object is represented by its data and methods ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > and methods are of no use outside a process (cannot be written out), maybe it > is better to not define external data as an object (at least in C++). Objects encapsulate: - knowledge of state information - operations (and their corresponding methods) - other objects, i.e., there can be: - homogeneous composite objects - heterogeneous composite objects - exceptions - constants - concepts If an object is a composite object, then you have your original problem defined recursively. Specifically, if you have large objects which are built on smaller objects, which are themselves built on still smaller objects, you have a very interesting "objectification" problem. On another matter: suppose a distributed application is, for example, constructed using a different object-oriented programming language at each node. The language at node X supports exceptions as part of a class definition. The language at node Y supports constants as part of a class definition. The language at node Z supports assertions as part of method definition. Suppose further that the language used at node W does not directly support some, or all, of these items. This obviously will have some impact on "objectification" strategies. [Before you say, "no one should ever attempt such a thing," consider this. Even if a single object-oriented programming language is used in a distributed application, there are still the issues of: - interfacing this system to other similar systems - enhancements to the original object-oriented language which may require a phased introduction of new software on the network - a decision to change the implementation language (or a desire to have the flexibility to make that decision) before all nodes are brought on line. This will probably only be an issue in systems which take years to develop and deploy.] There are quite a number of other issues and solutions I would like to discuss, but I have already taken enough space. -- Ed Berard (301) 353-9652