Sean O'Dell wrote:
> To manipulate a string, the Text object needs *no* input from the Image 
> object.  It's job is to manage a string.  That's all it does.
> 
> The Image object, however, needs to know about MANY different object 
> types because it receives them as input for determine how to manipulate 
> the image.  It manages an image buffer.  That's all it does.
> 
>  From that, I can only envision image.draw(text) as the most logical 
> pattern.

If you step back and try to think about these things in the real, 
physical world, every object would need to have a method for interacting 
with every other object, but to different extents.

Take a rock, paper, and a pair of scissors.  ;)

When the scissors and rock interact, they are both affected by the 
interaction, the rock could be marked by the scissors, or perhaps even 
chipped; the scissors could be broken by the rock.  When the paper and 
scissors interact, it is almost exclusively the paper that is affected, 
but after cutting thousands of pieces of paper, the scissors will be 
slightly dulled.

This is simply Newtonian physics.  For every action there is an equal 
and opposite reaction.

Typically in OO programming it is convenient to assume that only one of 
two objects is affected by their interaction.

The "Image" object in the example is similar to real-world paper, you 
draw on it, cut it, etc.  In interactions with other things, it is 
_fragile_ and easily affected.  A "Pen" or "Pencil" in a typical drawing 
program is similar to a real-world pen or pencil.  When it interacts 
with "Paper" (or Image objects), it is mostly the paper that is 
affected, not the pen.  On the other hand, in the real world pencils do 
get dull and pens do get empty, but mostly in OO design we are using 
idealized representations of pens and pencils which don't get dull or empty.

If we don't care about pencils getting dull or pens getting empty, we 
can simplify our software.  For this reason, when we're drawing on an 
Image objects in software it often makes more sense for the Image to be 
the receiver of the message, not the sender, and for the code 
implementing changes to be in the Image, not in the Pen.

Sometimes having the affected object be the receiver can have some 
strange effects though.  paper_obj.draw(pen_obj) may make more sense as 
a programmer, but it is strange that a it seems to be the paper drawing, 
and not the pen.  In this case, it might make more sense to make it 
paper_obj.getDrawnOnBy(pen_obj) but that's both long-winded and odd-looking.

Unlike the pen and paper example, there are situations when two objects 
both have to be affected by an interaction.  Take a person withdrawing 
money from an ATM  The person is affected by his/her money count going 
up, the ATM is affected by its money count going down.  In this case, 
both objects are strongly affected by the interaction.  Although in 
reality this is one atomic transaction, it is normally done as two 
transactions, and some external means is used to make sure that both 
sides of the transaction happen.

Which makes more sense here?

customer.getMoneyFrom(atm)
atm.giveMoneyTo(customer)

I think your answer to the question depends on how you've designed your 
objects.

 From what I can see, the way methods are typically assigned to objects, 
typically it is the object which is most affected by the interaction 
which has the method attached to it.  In the situation where a string is 
being printed, the string is typically unaffected by that interaction, 
however the output stream is affected, so the "print" method is attached 
to the output stream.  When both objects are affected the rules are more 
arbitrary, as I said before, it depends on how you've designed your 
objects.  Failing that, the rule seems to be that the interaction is 
described in a sentence in the most natural subject->verb->object way, 
and the subject of the sentence becomes the object to which the method 
is attached.

I suppose a more pure, real-world OO system would have objects with only 
attributes, no methods, and methods would be defined as things operating 
between two objects.  Instead of belonging to one class or the other 
one, the methods would be shared between the two.  What the syntax of 
this type of method call would look like?  I have no idea.

Luckily, most of the time when we're programming, we're dealing with 
things at an abstract enough level that we can have objects which are 
not affected when they interact with other objects.  When we print a 
string, only the output is affected, and not the string, so only the 
output needs to have a method.

My $.02

Ben