[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Java Tip 68: Learn how to implement the Command pattern in Java - JavaWorld - February 1999



Ooops ... as Barry pointed out:

> Can someone say why switch-statements are bad?  Surely, it's not
> a sudden worry about run-time efficiency -- a well-optimised
> switch-statement compiles to a computed goto ... which has linear
> execution time ... the same as following a pointer to find the code??

I had meant to say, of course ;-)

> switch-statement compiles to a computed goto ... which has unit
> execution time ... the same as following a pointer to find the code??

Rick mentions:

> There is also the issue that switch statements are inherently not
> extensible, at least not in the manner that sub-classing is considered
> to be.

True.  But, then, I've not found sub-classing to be a particularly
useful mechanism for extending (i.e. re-using) code.  At least, not
when the examples start to get non-trivial.

CASE STUDY
==========

To support this, look at the experience people had with the original
mechanism for handling GUI events in the JDK1.0 version of the AWT.
To receive a mouse click (say), we had to extend a class that had
a null-implementation mouseClick (I forget it's actual name) method
and override that mouseClick method to give it a body that did
whatever we wanted done whenever a mouse click occurred.  Now, that's
the perfect `object-oriented' way of doing things ... you use
sub-classing to override the method to extend its functionality
to whatever you want.

Except that people found this mechanism very hard to work with when
they scaled up the complexity of their applications.

In JDK1.1, such event handling was deprecated and replaced with
a traditional (non-`object-oriented') listener-callback mecahnism.
That gave us something much easier to use and led to much simpler reuse
of code and design and made the scaling up behavioural complexity much
easier.  What does this say about the benefits of `object-orientation'?

In JavaPP (JCSP or CTJ), those callbacks are transformed into channel
communications which -- claim -- gives even better decoupling (and, hence,
reuse) and, of course, greatly simplfied multithreading.

MOAN
====

In JDK1.1, they didn't transfor *all* event handling into callbacks.
In particular, they left the paint/update mechanisms in the old JDK1.0
`object-oriented' style.  To do *any* drawing on a Canvas (say),
we *have* to extend it and override its paint/update methods (which
get called by the JVM Event thread which passes in the needed Graphics
context).  I find this counter-intuitive and very hard to work with
for any complex drawing ... and for the same reasons, I bet, as people
found the mouseClick (etc.) overriding difficult.  So, I always
sub-class a Canvas, give it a `Paintable' callback registration
interface and override its paint/update methods to make a user
supplied callback.  Then, I can work with it ... but I wish it
was in the standard JDK.

Of course, for JCSP, it would be nice to turn the paint/update
callbacks into channel communications.  But there seems to be
an undocumented constraint that it *must* be the JVM Event
thread that executes these methods.  Sending the Graphics context
down a channel and executing it in an application process doesn't
work - even if we block the Event thread until this has finished.
Can anyone confirm this or know why it is true?  The *new* version
of JCSP does its best to work around this ... by introducing a
special kind of `Display' channel that connects an application
process to a display object ... the application process just
send Draw commands down that `channel'.  It's not a real CSP
channel though ... just a passive safely-shared-memory pool.
It could be *modelled* as an active CSP server process ... it just
can't be *implemented* as one because of the above JVM-imposed
constraint.

Note: there may be a similar, but for different reasons, problem
for configuring Swing components - see below.

SWING, THREAD-SAFETY and PROCESSES
==================================

One other point that I meant to mention, and seek information on,
yesterday.  The configuration methods of the new Swing classes are
explicitly documeneted as not being thread-safe.  The original web
notes just said not to use multithreading for GUI building - despite
its obvious attractions in this area - because (a) multithreading
was too hard anyway and (b) Swing was just not thread-safe.  Later,
they softened on this and said that you *could* configure Swing
components from multiple threads, but only if you used a method
called (I think) `invokeLater' which used the tricks described
yesterday (and in Java Tip 68) to delegate the actual execution
of the configurastion to the JVM Event thread.

My question is: does the un-thread-safeness of Swing configuration
methods just mean that we can't invoke them safely from multiple
threads?  If so, then the JCSP ActiveComponent process approach
- with configuration *channels* - solves the problem.  Each Swing
GUI would have its own process (i.e. thread) which invokes the
configuration methods on itself.  The application processes (i.e.
threads) that send the configuration *messages* do not invoke those
methods themselves.  From the process-oriented design viewpoint,
those application processes *are* configuring the GUI widget.
>From the JVM viewpoint, they are not ... only one thread ever
configures each component ... so we get ActiveSwing components
that are thread-safe.

OR ... does the declared un-thread-safeness of Swing configuration
methods mean that they *must* be executed only by the JVM Event thread
(i.e. using `invokeLater')?  That would be the case if those configuration
methods indulged in further thread-unsafe interactions with some system
objects - e.g. whatever manages the screen display.  This would be
pretty rotten, but is imaginable.  In which case, each JCSP ActiveSwing
components would have to have the internal process that services its
configuration channel also invoke `invokeLater', rather than execute
the configuration directly.  This would be a bore but it would remain
hidden to the application processes who just send configuration
message as before.

Does anyone know?  Haven't had time to investigate!

Cheers,

Peter.