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 autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 1108a1,23cd1575a227bc41 X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,23cd1575a227bc41 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-10-12 21:48:21 PST Newsgroups: comp.lang.ada,comp.object Path: bga.com!news.sprintlink.net!howland.reston.ans.net!europa.eng.gtefsd.com!newsxfer.itd.umich.edu!gumby!yale!yale!yale.edu!noc.near.net!ray.com!news.ray.com!news.ed.ray.com!swlvx2!jgv From: jgv@swl.msd.ray.com (John Volan) Subject: Re: Decoupled Mutual Recursion Challenger Date: Tue, 11 Oct 1994 23:34:03 GMT Message-ID: <1994Oct11.233403.25558@swlvx2.msd.ray.com> References: <1994Oct7.130100.26953@swlvx2.msd.ray.com> <1994Oct7.165517@di.epfl.ch> <1994Oct7.222716.8690@swlvx2.msd.ray.com> <1994Oct11.122356@di.epfl.ch> Sender: news@swlvx2.msd.ray.com (NEWS USER) Keywords: Ada 9X, object-oriented, decoupled mutual recursion, "withing" problem Organization: Raytheon Company, Tewksbury, MA Xref: bga.com comp.lang.ada:6849 comp.object:7301 Date: 1994-10-11T23:34:03+00:00 List-Id: Robb.Nebbe@di.epfl.ch (Robb Nebbe) writes: >|> I should point out that, in any object-oriented application, >|> responsibility for *many* aspects of the system's functionality winds >|> up being distributed across *many* classes of objects. >This is the way it should be. However, you are suggesting that a single >aspect of the system's functionality be distributed accrossed multiple >packages, which isn't the same thing. I am indeed suggesting that a *single* aspect of system functionality can be, and often should be, distributed across multiple classes (and therefore, packages). That's what I thought I said in the quote above, but obviously, my phrasing wasn't very clear. Let me rephrase: It's *often* the case that if you take any *particular* *single* "functionality" of an object-oriented system, you might *not* find that functionality totally encapsulated within any *one* object class. Instead, that functionality may actually be manifested as a multitude of similar methods scattered over many different classes of objects. Each of these methods only deals with that "functionality" directly in terms of its own particular object class, and that is as it should be. However, there may very well be *collaborations* among these methods: Any one of these methods, in any one of these classes, may wind up calling the corresponding methods in one or more of the other classes, and these may wind up propagating related calls to yet other classes, and so on. But the "algorithm" for that overall system functionality never appears completely in one place. The only way to visualize the "algorithm" is to trace the collaborative propagation of method calls across the various classes. That, I think, is the difference between functionally-designed systems and systems designed in an object-oriented fashion. In a functionally-designed system, you may very well see a major system functionality manifested as a single module of code. The algorithm can be found all in one place, but it winds up touching many different types of data. Other functional modules may wind up touching all of the same data types. So if you ask the question "What code affects this one particular data *type*?" you will not be able to find the answer encapsulated in any one place. You wind up having to search through all the functional modules. On the other hand, in an object-oriented system, we make the data types (i.e., the object classes) central, and the functions become secondary. Any one class of object may participate in many different areas of system functionality, to its own extent. But those same functional areas might also be dealt with partly within many other object classes as well. So if you ask the question "What code affects this one particular data *type*?" the answer is simple: the methods in this class. But if you ask the question "What code implements this particular *functionality*?" you wind up having to search through many object classes to find it all. As I said before, this difficulty in "seeing" overall functionality within an object-oriented system is only a symptom of *code*. Object-oriented *analysis* and *design* techniques have the liberty of presenting multiple complementary views to show different aspects of a developing object-oriented system. These views can include functionally-oriented "cuts" at the design, where you can focus on just those object classes, and just those methods of those classes, that pertain to a given functionality. That way, you can get a sense of the overall "algorithm" implemented by these disparate methods, by seeing their pattern of propagation. But just because you provide such a view during analysis or design, does *not* suggest that your final implementation must have a functionally-oriented module that totally encapsulates all of those methods in one place. >Your solution seems to contradict itself. You want to put the >abstractions in separate packages which suggests loose coupling but >you want them to include pointers to each other which suggests tight >coupling. You seem to be sitting on the fence trying to decide which >side you want to be on. Face it: OBJECT CLASSES WILL BE COUPLED TO EACH OTHER TO THE EXTENT THAT THEY SHARE RESPONSIBILITIES FOR OVERALL FUNCTIONALITIES OF THE SYSTEM. This coupling is everywhere. But how *deep* must this coupling be? Can we limit the coupling to having one separately-encapsulated module make calls to other related, yet still separately-encapsulated, modules? Or do we wind up having to encapsulate all classes within a single module, every time we find some functionality that they share responsibility for? >In article <1994Oct7.222716.8690@swlvx2.msd.ray.com>, jgv@swl.msd.ray.com (John Volan) writes: >|> C'mon, Robb, you are totally misunderstanding me. I am not claiming >|> that "my" implementation is the "best" one possible. I'm just claiming >|> that is one *possible* implementation. >... and for which you have seen good solutions but which don't >satisfy your constraints. I'm not claiming that there is no advantages >to implementing the relation with two pointers; I'm claiming that to >do that in two completely separate packages doesn't provide you with >any advantages. >If you want to implement a realtionship with pointers put the two >abstractions in the same package or in the same hierarchy of packages. >If you want to put them in completely separate packages then use an >ADT to handle the relationship. The issue of associations is only a particularly poignant special case of this overall issue of "functional coupling between object classes". You claim that I have only two choices for any association: (1) Have the two classes relinquish all responsibility over that association and give it to a third party, just so that the association can be encapsulated in one place; or (2) Let the two classes take on mutual responsibility for the association, but only if the two classes are encapsulated together as a single module, just so that the association can be encapsulated all in one place. The first choice means that we're giving up object-oriented encapsulation: It is no longer possible to say that all the code that relates *directly* to one particular class of object can be found encapsulated within the methods of that class -- you have to hunt through all the association modules, too. The second choice also gives up on object-oriented encapsulation: Object classes no longer act as the units of modularity/encapsulation/separate compilation at all! Two choices, both giving up on object-oriented encapsulation -- that's it, take it or leave it? I don't buy that. I think there is a third alternative: Distribute the responsibility -- we'll live with that -- but still keep the classes separately encapsulated. I say again: It *can* be done. True, it's not *built in* to Ada9X. But Ada (even Ada 83) has always had certain facilities for *extending* the language beyond its *built in* capabilities. That should be suggestive. If any of you folks out there think they have a solution -- in particular, if anyone thinks that exploiting inheritance is the answer -- then I challenge you to take the acid test: Show that your solution can handle even the situation of one class in a mutually-recursive association with one of its own subclasses. I fully intend to demonstrate that my own solution can satisfy this test ... but I don't want to spoil it for those of you who enjoy a challenge ... :-) -- John Volan -------------------------------------------------------------------------------- -- Me : Person := (Name => "John Volan", -- Company => "Raytheon Missile Systems Division", -- E_Mail_Address => "jgv@swl.msd.ray.com", -- Affiliation => "Enthusiastic member of Team Ada!", -- Humorous_Disclaimer => "These opinions are undefined " & -- "by my employer and therefore " & -- "any use of them would be " & -- "totally erroneous."); --------------------------------------------------------------------------------