Re: OO Principle - reference needed
- From: "Leslie Sanford" <jabberdabber@xxxxxxxxxxxxxxxxx>
- Date: Thu, 19 Apr 2007 21:48:45 -0500
"H. S. Lahman" wrote in message:
Responding to Sanford...
I have a question about setting up collaborations. Let me give a
trivial example. Say an object uses a timer. It doesn't create the
timer itself, rather the timer is passed to it when it is created.
The object that uses the timer stops and starts the timer as it
pleases and consumes "tick" events generated by the timer. My
question is whose responsibility is it to ensure the integrity of the
relationship between the two object?
First, some background to make sure we are on the same page. We have:
[SomeObject]
| *
| provides timer notifications to
|
| R1
|
| initializes
| 1
[Timer]
I was thinking of a one-to-one relationship. I think the above describes
one-to-many?
<snip>
To continue with the example, the consumer, i.e. the object that uses
the timer, makes certain assumptions. It assumes that when it starts
the timer, it's not already running. And when it stops the timer no
one else will start it again. In other words, it's in control of the
timer.
This is a much broader issue that is related to the fundamental way
the OO paradigm approaches collaborations.
In fact, SomeOBject has no expectations about Timer; its
implementation should not even know that a Timer exists. The whole
point of the OO paradigm is to eliminate the hierarchical
implementation dependencies implicit in the Do This approach of
traditional functional decomposition where the message sender
/expects/ something to be done.
As a result, messages in the OOA/D are supposed to be announcements
(I'm Done) and they are peer-to-peer to avoid hierarchies. To provide
an announcement the object only needs to understand itself and not its
context.
It is the job of the developer to connect the dots of the OO solution
in the OOA/D by mapping announcement messages to objects that care
what is being announced. In UML one does that in an Interaction
Diagram that is at a higher level of abstraction than individual
object methods. So, in theory, one can define collaborations after all
of the object methods have been defined and implemented.
I'm going to expand on my example a bit. Let's say that SomeObject
represents a MIDI file player (I use MIDI as an example because I'm
familiar with it). It needs timer notifications to drive playback of
MIDI data. If the timer is passed to the Player's constructor, the
player can connect to the timer to receive the tick notifications as
well as start and stop the timer whenever it needs to do so. However, if
we set things up so that the Player doesn't know about the Timer, then
we need a way for the periodic ticks generated by the timer to be
delivered to the Player, as well as starting and stopping the timer when
appropriate.
Keeping this as simple as possible, one approach would be to have a Tick
method in the Player's interface. This will need to be called in
response to the timer's Tick event, so an infrastructure is needed to
respond to the timer and pass along the message. Also, the Player needs
to announce when it requires the timer's services. So a typical scenario
could be that a Play method is called on the Player. This causes the
Player to send a message that it is playing (or at least wants to play).
The infrastructure receives this message and fires up the timer. The
timer generates timing messages which are then delivered to the Player
via its Tick method.
I'm going to get a little dirty with some code. This is in C# and uses
anonymous methods to connect the objects together:
Player player = new Player();
Timer timer = new Timer(10); // Raise ticks events every 10ms.
// Playing is an event raised by the Player when the Play method is
// called (assuming the Player is in a idle state, i.e. ready to play).
player.Playing += delegate(object sender, EventArgs e)
{
timer.Start();
};
// Stopped is an event raised by the Player when the Stop method is
// called (assuming the Player is already playing).
player.Stopped += delegate(object sender, EventArgs e)
{
timer.Stop();
};
// Tick is an event raised periodically by the Timer when it is running.
timer.Tick += delegate(object sender, EventArgs e)
{
player.Tick();
};
The syntax may seem a little odd if you're not familiar with C#, but
basically this sets up anonymous methods to delegate the events raised
in the player object to call methods in the timer object and vice versa.
In other words, the anonymous methods act as a delivery system for
events raised in one object to be sent via method calls to another
object.
My question is does the mechanism I've used above represent, at least in
spirit, what you mean by "I'm Done" announcements?
(BTW, "Playing" and "Play" may not be the best names here because they
imply that the Player is in fact playing when in reality it won't do
anything until it begins getting tick messages via its Tick method, so
maybe some other names would be more appropriate).
The beauty of this approach is that Player and Timer are completely
agnoistic to the other's existance. We're free to "connect the dots"
without the objects knowing about each other.
Getting back to my original concern, based on what you've said, it would
be the responsibility, if I understand correctly, of the one setting up
this collaboration to make sure that the objects play nicely. For
example, during a play session, you wouldn't want the Tick method on the
Player object called indiscriminately by someone else because it could
screw up the timing of the playback. It's up to the one setting up the
collaboration to ensure this doesn't happen.
I'm snipping what you said below about DbC, but want you to know that
I've seen you discuss this before and your explanation here further
illuminates the concept. I now have a better understanding.
.
- Follow-Ups:
- Re: OO Principle - reference needed
- From: H. S. Lahman
- Re: OO Principle - reference needed
- References:
- OO Principle - reference needed
- From: Nathan
- Re: OO Principle - reference needed
- From: H. S. Lahman
- Re: OO Principle - reference needed
- From: Leslie Sanford
- Re: OO Principle - reference needed
- From: H. S. Lahman
- OO Principle - reference needed
- Prev by Date: Re: OO-Inquisition
- Next by Date: Re: OO-Inquisition
- Previous by thread: Re: OO Principle - reference needed
- Next by thread: Re: OO Principle - reference needed
- Index(es):
Relevant Pages
|