Comrades: 
 
Two (long-winded) things: 
 
1. I have changed our Model interface and the associated listeners and
events 
to make them a bit more useful and understandable: 
 
a. Over the last few weeks I have checked in code that changes the
types of 
events passed into the various methods implemented by listeners; e.g. 
CollectionChangeListener.itemsAdded(...) now takes a CollectionAddEvent
instead 
of a CollectionChangeEvent. This reduces the amount of
"overloading" we did 
in the past where events had state that may or may not have been
relevant to the 
listener, depending on the listener method that was being called at the
time. 
This should make it easier to code listener implementations. 
 
b. I just checked in some other changes to Model: You can no longer add
a 
PropertyChangeListener (or CollectionChangeListener etc.) to a Model
without 
specifying an aspect name. I replaced this type of behavior with a new
interface, 
ChangeListener, that extends all of our other listeners
(StateChangeListener, 
PropertyChangeListener, CollectionChangeListener, etc.). 
This listener can be added to a Model without specifying an aspect name. 
It will receive notification of any changes to the Model
(property, collection, or otherwise). 
This seems much more useful that supporting listeners that were
notified of all 
the changes to a Model of a particular type (property or collection
or...). Now, if 
appropriate, you can develop a single listener that will be notified of
all model changes 
to a particular object. And, if you want to really simplify your
listener and blindly 
synchronize with the model with any change, you can use the
implementation 
CommandChangeListener and implement a single method to respond to any
and all model 
changes. 
 
2. I would like to investigate using Iterables instead of Iterators in our API. 
 
For years we've nicely encapsulated any "contained" collection by
returning an iterator 
on the collection instead of the collection itself. To prevent
ConcurrentModificationExceptions 
we have usually used a CloneIterator: 
 
    public Iterator<Bar> bars() { 
       return new CloneIterator<Bar>(this.bars); 
    } 
 
(Of course, this requires the collection be synchronized [typically as
a Vector]; and many of 
our collections are not synchronized. That's is another
discussion....) 
 
When WTP finally moved to JDK 1.5 and we could use Iterables and the
new 'foreach' 
loop syntax, I looked briefly at how we might start returning Iterables
from our model 
instead of Iterators. This would make it much easier to loop over
objects in our model. 
Unfortunately, I didn't do a very good job - all my ideas were not very
appealing.... 
Anyway, a while ago, I came up with a way to start using Iterables that
was only a minor 
change from how we use Iterators and takes advantage of all the various
Iterators we 
already use (e.g. CloneIterator, TransformationIterator,
FilteringIterator): 
 
    public Iterable<Bar> getBars() { 
       return new LiveCloneIterable<Bar>(this.bars); 
    } 
 
(Why the Iterable is a LiveCloneIterable and not just a CloneIterable
is yet another discussion....) 
 
Anyway, I would like to try changing some of our more isolated API
(e.g. maybe the database 
stuff) to start returning Iterables and see what happens.... 
 
I would appreciate any feedback. Maybe we can discuss this stuff in our
meeting(s) next week? 
 
Thanks. 
Brian 
 
 |