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
|