From: H. S. Lahman on
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
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
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

"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
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