[Removed cl.forth, added and set F'up2 to comp.object]
I didn't follow the (predictably) ensuing flame war closely, so I'm not
sure if this has been addressed. If it has, I apologize, but I didn't see
it. And sorry I'm a bit late in this.
In message <
[email protected]>,
Tom Dyess wrote on Sun, 13 Feb 2005 12:36:26 -0500:
[...]
I know absolutely nothing about SmallTalk, but this seems very strange to
me. Are you talking about inheritance?
No, message-passing is a customary generic OO term for describing the
interaction between objects. They send each other messages. Since message
passing has had some other connotations for quite some time that aren't
necessarily supposed to be implied by the term in OO, Jacobson for
example prefers to speak of stimuli (no idea if that alternative has been
widely accepted in the OO community). What it comes down to is that you
trigger some behavior in the receiving object, whether you say by sending
it a message or by giving it a stimulus.
In the context of Java, a method call is a message/stimulus. Returning
something to the caller of a method is a message/stimulus. Throwing an
exception is a message/stimulus.
I think this generic terminology is often employed to emphasize the
decoupling of message sender and receiver achieved through polymorphism,
abstraction and encapsulation (in varying proportions).
[...]
You should always define variables in the lowest scope possible. There is
nothing wrong with local variabes, on the contrary, it's bad form to have a
bunch of global variables, but you will probably always have them, just try
to keep them to a minimum. For example, in a servlet, I keep my DB
connection/pool in a global scope in the servletContext. It doesn't make
sense to create them locally.
[...]
What you say is true, but I think he wasn't referring to local
vs. global variables at all. Instead, I think he meant the proliferation
of method-local variables that serve no other purpose than to be able to
call a method on (send a message to ;-) ) that object, when a cleaner
design would have the object the reference originated from delegate
correctly instead. To illustrate:
Compare and contrast
A a = registry.getSomeA( x ); // just to get started somewhere
B b = a.getB();
C c = b.getC();
D d = c.getD();
d.doSomethingUseful( y );
with
A a = registry.getSomeA( x );
a.doRealWork( y ); // a relays to its b, b to its c, and c to its d.
(Going from the first to the second form is known as the Hide Delegate
refactoring. Notice that a.getB().getC().getD().doSomethingUseful()
wouldn't be an improvement over the first form.)
Note I intentionally named the method on A differently, because to A's
clients another name might be much more appropriate and descriptive than
doSomethingUseful(), which in turn might be perfectly appropriate for D's
clients. But a calling sequence as seen in the first version strongly
suggests the calling code shouldn't really be a client to a D, but rather
to an A. As an added benefit, a, b, and c can all choose to decorate d's
behavior (or decline to do so) instead of simply passing the message
through 1:1. (See how the message passing mode of thinking about it can
be useful?)
While there certainly are cases where constructs as in the first
version are ok (well, maybe not quite that extreme), in general terms I
would claim the second way is _much_ more OO. The first way forces the
calling code to have intimate knowledge of the composition not only of A,
but of B and C, as well as of D's behavior. In the second example, it
only needs to know someone who knows someone who knows someone... who
knows how to do something. Hence, better encapsulation. Of course this
can harbor its own problems, but enough rambling for now. ;-)