Re: General OOA/D/P issues

From: Mark Nicholls (Nicholls.Mark_at_mtvne.com)
Date: 08/13/04


Date: 13 Aug 2004 04:49:34 -0700

Ok, I got to the end of this message, the problem with long messages
is I tend to write responses to them as I go through reading them, and
by the time I get to the end the bits I put at the beginning are out
of date, so to save my blood pressure and your lawn I'm going to do a
massive
<snip>
</snip>

most of snips seemed to stem from your use of the word subsystem.

I think you consider a module and class libraries to potentially be
subsystems.

If you want to snip stuff back in do so.

> >
> >>What you have is a classic functional decomposition tree:
> >>
> >> [Person] <------------- [Client]
> >> / \
> >> / \
> >> / \
> >> [Mouth] [Stomach]
> >>
> >>Person is just a high-level function node in that tree. Whatever
> >>contracts exist between Client and Mouth or Stomach must be expressed in
> >>the contract with Person. Therefore Person's specification must include
> >>the specifications of Mouth and Stomach. So Mouth and Stomach are
> >>extensions of what Person is and any changes are likely to involve all
> >>three. That is exactly the sort of hierarchical dependency that led to
> >>SA/SD/SP spaghetti code.
> >
> >
> > I accept the point, but the argument runs against my interpretation of
> > encapsulation.
> >
> > I would say there is a contract between Client and Person, I am at
> > liberty to change the contracts between Person and Stomach or any
> > other hidden implementaion of the embedded model as long as it doesn't
> > contravene the contract already in place.
>
> You are overlaying a specific semantic on the collaboration. The more
> general statement of the OO approach is that there is a contract between
> Client and whoever provides the service. If one has decomposed Person
> and delegated the eating responsibility to some other entity, then
> Client's contract transfers with that delegation.

not in my head it doesn't the contract exists at the type level, and I
am free to subtype and internally implement eat in any way shape or
form, as long as it doesn't contravene the contract on the base type.

I wave a magic wand, chant LSP and it all magically works.

<snip>
</snip>

>
> Carrying your point to its logical extreme, I could also encapsulate
> Client and Person in some Container object and let them talk to one
> another within the container's implementation. Ultimately, I would only
> need one public Main object for the entire application solution. Now
> that seems pretty silly but where would you draw the line in the sand
> that would yield peer composition objects that talked to one another?

That's not at all silly, that object is called an application and it
has a single method

void main(argc,argv)

and the collaboration is between the operating system and the
application.

AND outside that model there is another one, where user interacts with
the object called the application through the operating system that
delegates button clicks etc to the application in order to product the
desired behaviour.

and there are economic models that encompass that, that know nothing
about the specifics of how I interact with my computer, etc.etc.etc.

<snip>
</snip>

> >
> >> 1 eats with 1
> >>[Person] ------------------- [Mouth]
> >>
> >>While a mouth is part of a person in some contexts, that Whole/Part
> >>characteristic may or may not be interesting to the problem in hand.
> >>Assume it is so that in UML we have:
> >>
> >> eats with 1
> >>[Person] <*>---------------- [Mouth]
> >>
> >>The only constraint this places on the OOP implementation is that the
> >>instance and Mouth must live and die with the instance of Person.
> >>Before the problem space decomposition Person has a responsibility for
> >>eating. Now we have decomposed Person into two entities, Person and
> >>Mouth. Where does the eating responsibility go?
> >
> >
> > If mouth is a "top level" entity from the perspective of the client,
> > then mouth.
> > If it is possible to encapsulate that entity at a different level of
> > abstraction then it would usually disappear and person would
> > *delegate* to mouth.
>
> The context here is that one has already decided that Person /must/ be
> decomposed and Mouth /is/ a relevant decomposition entity. At that
> point one can no longer hide it when it is involved in a collaboration
> with another entity. (At least not if one is following the OO paradigm;
> in functional programming it would be quite laudable.)

nope.

OK if I go

public interface IConsumer
{
    void Eat(Food);
}

public class Person : IConsumer
{
    private Mouth mouth = new Mouth();

    public Person()
    {
    ...
    }
    void Eat(Food)
    {
       this.mouth.Eat(food);
    }
}

internal class Mouth : IConsumer
{
    void Eat(Food)
    {
        ...
    }
}

now what have I defined?

Person, mouth and implicitly a client that uses Person via IConsume.

as far as the client is concerned there is no such thing as mouth, as
far as Person is concerned it knows there is a client but not who that
is, and as far as Mouth is concerned it knows nothing except, some
client at some point will use it (I could if I want put it in a
completely seperate module and then it would not even potentially be
able to see class Person).

"At that point one can no longer hide it when it is involved in a
collaboration
with another entity" - but mouth is hidden from the client.

<snip>
</snip>

> >
> > To me it's weak delegation i.e. message passing, Mouth should be
> > private from the client otherwise you get 2 classes doing the eating.
> >
> > If Mouth is part of or associated with Person seems academic to me.
> >
> > class Person
> > {
> > public:
> > Mouth NavigateToMouth()
> > {
> > return itsMouth;
> > }
>
> This instantiates relationship navigation. It could just as well have
> been "Mouth getR97 ()" or "Mouth getSecondReferentialIdentifierFromLeft
> ()" because the semantics of Mouth, Person, and Client is completely
> irrelevant to the navigation. This is important because...

the syntax is irrelevant, but not the semantics, you have defined that
Person knows which mouth is it's own, that is semantic to me. A fork
lift truck would not be able to do this.

>
> > private:
> > Mouth itsMouth;
> > };
> >
> > class Mouth
> > {
> > public:
> > void eat(Food bite)
>
> Now the /only/ message sent to implement the collaboration is this one
> from Client to Mouth. Navigating the relationship path also involves a
> message, but that is completely orthogonal to the semantics of the
> collaboration.
>
> > {
> > ....
> > }
> > }
> >
> > client code....
> >
> > Person p = new Person(...);
> > Mouth m = p.NavigateToMouth();
> > m.Eat(..);
> >
> > is this delegation ?
>
> Not in the Client. The delegation lies in Mouth having the
> responsibility rather than Person. But Client couldn't care less about
> that; it just needs to collaborate with whoever implements the
> responsibility. Everything else is just an addressing mechanism to get
> the Eat() message to the right place.

OK, good, its not me, I haven't misinterpreted you and we are not
wasting our time over a misunderstanding of each other i.e. we do
completely and utterly disagree what delegation is.

I'm actually pleased about it, because I wondered for a second whether
I had just misread something.

We may need to finish at this point with this discussion, I see little
way forward, to me this is not delegation its just navigation, and (in
my terms) to you delegation is bad.

In your terms, my implementation of delegation is bad, yet I may be
implementing all sorts of good delegation without even realising it.

<snip>
</snip>

> First, a parenthetical comment. When I learned about delegation it was
> in the '70s using SA/SD. In the '80s I learned to remap it to the
> general DOT view for objects. Our industry is notorious for co-opting
> terminology over time to mean much more specialized things than they
> originally meant (e.g., "client/server"). So it wouldn't surprise me if
> the modern usage is "forwarding". I just prefer the more generic view.

quite possibly.

<small snip>
</small snip>

>
> While daisy-chaining Client -> Person.eat -> Mouth.eat -> Stomach.eat
> might seem cleaner because only Mouth's implementation changes in this
> example, that is highly deceptive. The chain represents a hierarchy of
> behavior specifications. The specification of Person.eat from the
> client's view is exactly the same as the specification for Stomach.eat
> in a pure forwarding context.

It's actual absolute behaviour and the specification of that behaviour
is changed yes but the conditions placed on person.eat are potentially
much less than a complete specific definition (otherwise you cannot
subtype ever), so as long as any change to a member in the chain does
not contravene it's super types contract and then I invoke LSP and all
is done.

<small snip>
</small snip>

>
> Now I'm off to mow the $%#@&*! lawn so I'll respond to the other message
> lateer or tomorrow.
>

We can agree to disagree, rather than ruin the lawn.

It's one of those conversations that need to be done face to face over
a period of 6 months and several gallons of beer, and even at the end
of all that we'll still disagree.



Relevant Pages

  • Re: Building Contract. Please help.
    ... we do think the client has cohersed us into doing ... <pasting of contract wording> ... This quotation is a fixed price for the works to completion. ... Central pendant light fitting. ...
    (uk.legal)
  • Re: Please help. I am being sued through a court. How do I respond?
    ... had offered to prepare a standard JCT building contract but did ... The client provided the drawings, ... actual costs by ensuring that a full vehicle would ... site-manager and, crucially, the job had a supervising Architect, ...
    (uk.legal)
  • Re: Please help. I am being sued through a court. How do I respond?
    ... |> had offered to prepare a standard JCT building contract but did ... The client provided the drawings, ... The supervising architect was ... |> costs, ...
    (uk.legal)
  • Re: Doc always seems to be on vacation on previously proposed paydays
    ... Well, December 1st came, no pay. ... I'm told that they are having trouble with the client paying them. ... at this point I do start threatening lawsuits and finally around mid-February I get paid and they say they no longer have the account. ... They finally tell us that the client is looking at bringing in another company to "compete" for the contract renewal. ...
    (sci.med.transcription)
  • Re: TO has to stay
    ... mouth off. ... >>>If the Eagles do not pay out the roster bonus and keep TO at least ... >>>sign with the Eagles as long as Lurie and Banner are stilling signing ... >> They're not breaking the contract if they cut him before the bonus is ...
    (alt.sports.football.pro.phila-eagles)