From: H. S. Lahman on 1 Sep 2006 11:28 Responding to Kazakov... >>>I think Richard meant an automatic generation of wrappers for delegated >>>things. >> >>I don't see any wrappers. The delegation already exists in the problem >>space because the delegatee must be identifiable there to abstract it as >>an object (e.g., a role played by Strategy). IOW, all one does is >>change the level of abstraction of one's view of the problem space. > > > That's why it is no different from inheritance. To have inheritance, one must have a generalization and there is no generalization during delegation. Delegation is commonly used as an /alternative/ to generalization. >>Once one has identified the delegatee, then all one needs to do is >>implement a simple association between it and the delegator. > > > No. This is the same issue as we have discussed for LSP. There is no *the* > delegatee. Delegation is a relation between types, which [types] have > potentially unlimited set of instances. No, it is not a relation between types; the types are completely independnet in a delegation. A delegation just results in a reallocation of responsibilities among multiple peer objects rather than a single object. In some problem context I may have a notion of Car. That Car will have a drive train in the problem space. But if my problem context doesn't need to know anything special about the drive train (e.g., the application in an inventory control program), I can abstract the notion of a drive train as simply properties of a [Car] abstraction (horsepower, fuel consumption, etc.) without any delegation of generalization. OTOH, if my problem space is an auto assembly plant, the drive Train exists independently of the Car until it is incorporated in the assembly. So I need to model the Drive Train as an object independent of Car that becomes a component of a Car. But the Drive Train is not a Car in that context by any stretch of the imagination so no generalization relations exists between them. All one has is a simple conditional association between peer objects. In the second example one has reduced the level of abstraction to the level of individual, standalone components of an assembled Car. In so doing one redistributes the properties (HP, etc.) from Car (the delegator) to Drive Train (the delegatee). That is what delegation is about and it has nothing to do with generalization. >>In an OO >>context there are only three ways to do that: passing an object >>reference in a message, using a pointer referential attribute, or >>conducting a class search based on explicit object identity. > > > Implementation details... True. But I was just making the point that even at the OOP level where one deals with type systems, one implements delegation differently than generalization. >>>My position is that when this is supported, then delegation = inheritance. >> >>Even if one does employ somehow wrappers, all one has is a construct for >>indirection like Singleton or Facade. So I don't see any generalization. > > > Generalization is that as a type relation delegation is no different from > interface implementation. To me it is a form of inheritance [from the > interface]. But there is no generalization in Singleton or Facade. ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: Dmitry A. Kazakov on 2 Sep 2006 04:32 On Fri, 01 Sep 2006 15:28:46 GMT, H. S. Lahman wrote: > Responding to Kazakov... > >>>>I think Richard meant an automatic generation of wrappers for delegated >>>>things. >>> >>>I don't see any wrappers. The delegation already exists in the problem >>>space because the delegatee must be identifiable there to abstract it as >>>an object (e.g., a role played by Strategy). IOW, all one does is >>>change the level of abstraction of one's view of the problem space. >> >> That's why it is no different from inheritance. > > To have inheritance, one must have a generalization and there is no > generalization during delegation. Delegation is commonly used as an > /alternative/ to generalization. To me when the type S delegates its Foo to the Foo of the type T, then equivalently S inherits Foo from T, and equivalently, S is a subtype of T in Foo. Clean and unambiguous. >>>Once one has identified the delegatee, then all one needs to do is >>>implement a simple association between it and the delegator. >> >> No. This is the same issue as we have discussed for LSP. There is no *the* >> delegatee. Delegation is a relation between types, which [types] have >> potentially unlimited set of instances. > > No, it is not a relation between types; the types are completely > independnet in a delegation. A delegation just results in a > reallocation of responsibilities among multiple peer objects rather than > a single object. => types are related. You have identified a group of objects sharing some behavior, this is either a type or a class of types to me. >>>In an OO >>>context there are only three ways to do that: passing an object >>>reference in a message, using a pointer referential attribute, or >>>conducting a class search based on explicit object identity. >> >> Implementation details... > > True. But I was just making the point that even at the OOP level where > one deals with type systems, one implements delegation differently than > generalization. .... presently, in a languages that has no proper support for delegation. In a better language you wouldn't care how S::Foo is routed to T::Foo, exactly as you don't when you call to a virtual method. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: H. S. Lahman on 2 Sep 2006 10:19 Responding to Kazakov... >>>>>I think Richard meant an automatic generation of wrappers for delegated >>>>>things. >>>> >>>>I don't see any wrappers. The delegation already exists in the problem >>>>space because the delegatee must be identifiable there to abstract it as >>>>an object (e.g., a role played by Strategy). IOW, all one does is >>>>change the level of abstraction of one's view of the problem space. >>> >>> >>>That's why it is no different from inheritance. >> >>To have inheritance, one must have a generalization and there is no >>generalization during delegation. Delegation is commonly used as an >>/alternative/ to generalization. > > > To me when the type S delegates its Foo to the Foo of the type T, then > equivalently S inherits Foo from T, and equivalently, S is a subtype of T > in Foo. That may be a helpful view when dealing with 3GL types systems, but it is not the OOA/D view. >>>>Once one has identified the delegatee, then all one needs to do is >>>>implement a simple association between it and the delegator. >>> >>>No. This is the same issue as we have discussed for LSP. There is no *the* >>>delegatee. Delegation is a relation between types, which [types] have >>>potentially unlimited set of instances. >> >>No, it is not a relation between types; the types are completely >>independnet in a delegation. A delegation just results in a >>reallocation of responsibilities among multiple peer objects rather than >>a single object. > > > => types are related. You have identified a group of objects sharing some > behavior, this is either a type or a class of types to me. Once the delegation is identified the resulting object abstractions are independent peers. There is no sharing. >>>>In an OO >>>>context there are only three ways to do that: passing an object >>>>reference in a message, using a pointer referential attribute, or >>>>conducting a class search based on explicit object identity. >>> >>>Implementation details... >> >>True. But I was just making the point that even at the OOP level where >>one deals with type systems, one implements delegation differently than >>generalization. > > > ... presently, in a languages that has no proper support for delegation. In > a better language you wouldn't care how S::Foo is routed to T::Foo, exactly > as you don't when you call to a virtual method. Actually, you don't want to do that. The client wants to talk directly with the delegatee via relationship navigation rather than using the delegator as a middleman. IOW, objects collaborate on a peer-to-peer basis. The problem with using the delegator as a middleman is that the delegator no longer has the responsibility so it has no business knowing anything about it semantics. That is manifested by maintenance when new requirements demand that the interface to the delegatee change. If there is no middleman, then only the client and delegatee are affected. If there is a middleman, then all three have to change because the middleman does a pass-through of the delegatee's interface (i.e., the delegatee's properties must be defined in the middleman's interface for the client to access the properties). That is a major no-no in OOA/D. ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: adaworks on 2 Sep 2006 19:06 "H. S. Lahman" <h.lahman(a)verizon.net> wrote in message news:ixhJg.8950$4O4.2902(a)trnddc02... > Responding to Adaworks... > >> This conversation began as a discussion of delegation versus inheritance. >> Considering my previous paragraph, I am still wondering which programming >> language supports a model of delegation that does not require a call-return >> implementation. > > AFAIK, they all do. All one needs to do is define the delegatee, instantiate > a relationship to it, and navigate that relationship during collaborations. > For example, in the GoF Strategy pattern the delegation of Strategy is from > the Context entity: > > * R1 1 > [Context] ----------------- [Strategy] > A > | > ... > > Once one has extracted the [Strategy] delegation from [Context], all one has > to do is instantiate R1 with a pointer or somesuch to access a particular > Strategy from a given Context during a collaboration. > > But that's too easy, so I have to conclude I don't understand your point. > Specifically, what do you mean by "call-return"? > Languages such as C++, et al, depend on member functions for the implementation of methods. These, in turn, involve a call-return mechanism where a stack entry allows the method, at completion, to return to the point of the call and continue execution from that point. I pure delegation, a message is passed to a method in a delegator, the delegator can forward that message to a method in another class without the need for a stack entry. It is pure message passing mechanism. The delegator is an agent that simply sends the message on to the delegatee. When the delegatee has finished doing its work on the message, it does not unwind through the stack to pass back through the delegator. Consider this scenario. You are the supervisor of a group of people. You ask a member of your team to carry out some task. That team member assigns the task to one of his subordinates and indicates the source of the request. When the subordinate completes the task, s/he notifies the original requestor without having to first notify the foreman. This kind of delegation can be carried to several levels. It is highly efficient since there is no unwinding through the stack. It works best in a pure message-passing mechanism rather than in a call-return mechanism. Richard Riehle
From: ulf on 2 Sep 2006 20:19
H. S. Lahman wrote: > [...] > > Yes, *each* method/behavioral-property can be specified self-contained > > and in terms of its own input-to-output transformation [at least for > > the issue at hand]. > > But a class can say more about its instances than specify all their > > self-contained > > knowledge/behavior properties. It can also *relate* several of these > > self-contained properties eg. by an invariant. Such an relating > > invariant cannot be reduced to the self-constained specification of any > > of the object's knowledge/behavior properties. > > > > How do invariants fit into your presentation of OOA/D founded on > > self-constained responsibilities? > > Per the above, knowledge invariants are part of the precondition for a > behavior responsibility and they only apply to input state variable > values. In abstracting behavior responsibilities to be intrinsic and > self-contained the developer <methodologically> ensures that invariants > between behaviors do not exist. OK. Let me rephrase: Don't we need, besides responsibilities for behavior and for knowledge also a category of responsibilties for (knowledge) invariants? By my understanding of invariants and subclassing (cf. DbC), invariants in a class X cannot be completely reduced to preconditions of the behaviors in the same class, because invariants should also bind subclasses' behaviors, while preconditions of X's behaviors have no bearing on the (necessary) preconditions of new behaviors in X's subclasses. > > [...] > > A quibble, but technically this is not quite true. Consider Mass = > Volume * Density. If all three are defined as attributes, one has a > problem because Volume and Density might be updated with output values > from different behavior responsibilities. However, in OOA/D these > problem space invariants are treated specially by explicitly designating > the dependent and independent variables in the static description. That > signals the designer that referential integrity issues exist and must be > explicitly dealt with in dynamic description. Good point. > [...] > > > In model-based specifications, data/state-variables are passive. ... > > > > In responsibility-based specifications, invariants can be added to the > > [few] knowledge properties related by the invariant, ... > > ... > > My only quibble here is with model-based vs. responsibility-based. The > OO paradigm is responsibility-based. OTOH, the OOA/D notation (UML) is > model-based. So I am not sure I would contrast the approaches that way. "Model-based [formal] specification" cf. http://www.google.de/search?hl=de&q=model-based+specification is a standing technical term. UML + OCL (as well as a DbC-contract) is such a model-based specification in this sense for the instances of a class. UML regards its attributes as passive. They are not given responsibilities (other than linking ["knowing" ;^)] a value/object of a certain type/class). > [...] > So when one gets to instantiation of specific > set members one realizes that the tree is wrong and needs to be > something akin to > > [FourSidedPolygon] > + computeArea() > A > | > +-----------+----------+---... > | | | > [Rectangle] [Square] [Rhomboid] > + majorSide + side + majorSide > + minorSide + minorSide > + acuteInteriorAngle This is also my view: Square-object NOT is-a Rectangle-object > [...] > > [elided fruitless discussion about semantics of "depend on what the values are" / "look at values", maybe originating by the difference between "value" and "actual value" ] > > [...] > > FWIW, I agree with both schools. I agree with the first camp that the > public properties alone define what an object /is/. I think that is the > only way to map easily to the 3GL type systems that are based on > external property access. I agree with the second camp that one can't > express dynamics without defining internal static structure. So I just > see public vs. private as a notational convenience for separating the > What from the How. Agreed. Note: In model-based formal specifications, state variables of the OOA/D model which are necessary for behavior specification but do not oblige the concrete object to represent this state explicitly are sometimes known as "internal model variables" or "ghost variables", and in physical models they are called "hidden parameters". Regards, Ulf Schünemann |