[Biojava-l] Immutable objects and ChangeListeners

Forsch, Dan dorsch@netgenics.com
Mon, 15 Jan 2001 11:52:25 -0500


I don't want to beat this (cold) thread into the ground but I'd like to try
once more to clarify the point that I was making.  Someone (Thomas?) made
the point that the API's in BioJava should be geared towards support for
bioinformatics applications.  I agree with that but I don't belive there is
very much in the Changeable API or any change framework that is specific to
biological data.  BioJava's strength will be both in its support for common
bioinformatics tasks and in its leveraging the power of Java.  As such I
think the contributors should try to make use of the Java core libraries
whenever possible in order to emphasize compatibility.  

The PropertyChange API was developed for changes to JavaBean properties but
it is useful (and useable) outside of that context.  Changes to a
Distribution or SymbolList are not property changes, I agree, but the
distinction is really a semantical one which, IMO, doesn't justify
duplicating much of the purpose of that API.  It's also true that properties
which generate PropertyChangeEvents should have corresponding get/setters
but that is just a JavaBeans _convention_ and shouldn't be required to use
that API to represent changes in a more general way (incidentally, I think
that BioJava API's should use the get/set convention whenever possible, even
in non-GUI interfaces and classes).  As far as the type safety issue is
concerned, the same thing could be achieved with public String constants
defined in BioJava interfaces that is being done with public ChangeType
members.

I'll reiterate that I think Changeable is a superior model to
Property/Vetoable Change but the price of potential incompatibility is too
high IMO.  Consider the example of a GUI application using BioJava to model
the domain data and also using 3rd party JavaBeans in the UI.   A component
in such an application will likely have to be both a PropertyChangeListener
for the beans and ChangeListener for changes in BioJava objects.  If this
overlap can be bridged by adapters between the two API's then that solution
seems like a good compromise.

Dan Forsch, Principal Software Engineer
NetGenics, Inc.
1717 East 9th Street, #1600
Cleveland, OH  44114
phone: 206.374.4541


> -----Original Message-----
> From: Matthew Pocock [mailto:mrp@sanger.ac.uk]
> Sent: Wednesday, January 10, 2001 7:22 AM
> To: Forsch, Dan
> Cc: 'Mark Schreiber'; biojava-l@biojava.org
> Subject: Re: [Biojava-l] Immutable objects and ChangeListeners
> 
> 
> Hi.
> 
> Sory for the length of this - it's a bit of a mental vomit. 
> Events are cool.
> They allow you to know that objects are changing without 
> invalidating the
> encapsulation of the objects - fostering loose binding betwen 
> components.
> 
> The Java libraries seem to contain two types of event models. 
> Firstly, there is
> the interface based events, such as the 
> MouseListener/MouseEvent, where there is
> an interface for each logical group of parameters that may be 
> interesting to a
> listener, and the interface for that listener is defined. 
> There is one set of
> events and listeners for each logical group of events e.g.
> ActionEvent/ActionListener. This gives very good compile-time 
> binding, and is
> apropreate for cases where objects need to be informed of a 
> specific change and
> perform a specific response - handling a button press and the like.
> 
> The other extreem is exemplified by the
> PropertyChangeEvent/PropertyChangeListener api. These events 
> signify that a
> JavaBeans property on an object has altered (or is about to 
> alter). The property
> is specified by a string. This allows a single listener to 
> work with a range of
> event sources and property types e.g. a repaint listener may 
> well cause a GUI
> component to repaint if any of the objects it renders are 
> altered in any way.
> With the tight-interface way of doing things, you would have 
> to define one
> event/listener pair for each property, and have one listener 
> instance for each
> possible cause for a repaint. This hastle is obviated by the 
> loose binding of a
> property change event to its name at the expense of 
> compile-time sanity checks.
> 
> There are several restrictions to the PropertyChange API that 
> are not present in
> the Changeability API. Firstly, properties should realy map 
> to bean properties.
> As Thomas pointed out, many of the things that can change in 
> BioJava objects are
> not bean properties, but are still mutable state. OK, I sort 
> of made this up,
> but this is the spirit of the things.
> 
> Secondly, if I have two beans with a property 'font', there 
> is no way for me to
> know whether they are comparable properties. One may be the 
> font associated with
> a GUI component, another may be a font name as a String in a 
> wrapper arround a
> text box. The BioJava ChangeType objects provide a type-safe 
> way to clearly
> identify the 'type' of the event. Interfaces define how they 
> may change by
> listing public static final ChangeType instances. Since these 
> are defined within
> interfaces, it is clear when two changes are of the same type 
> because they have
> exactly the same ChangeType property in the ChangeEvent.
> 
> Thirdly, both of the event models above are shallow. That is, 
> you can discover
> that an object has changed, but there is no way to know what 
> caused that change.
> For example, if a widget says that it has resized, you don't 
> know if that is
> because the user resized a window or the underlying data has 
> changed. In the
> case of the GUI, this probably doesn't matter, but for our 
> applications it does.
> You can listen to an HMM's PARAMETER changes to be informed that some
> propability for transitions or emissions has altered. If you 
> get one of these
> events, you can then call changeEvent.getPrevious() to pull 
> back the event that
> a probability Distribution fired to indicate that it had altered. This
> maintainance of the complete 'chain of evidence' is key to 
> robustly handeling
> these events. The flip side of this is that 
> ChangeVetoException inherits from
> NestedException, which means that it can maintain a complete 
> 'chain of evidence'
> for why a change is being prevented by using the constructor 
> that takes a
> message and a causual exception. A listener on the HMM can 
> veto all PARAMETER
> changes, which will result indirectly in all changes to the underlying
> Distributions being vetoed. This gives us an extremely 
> powerful API for
> maintining object integrity.
> 
> I am very open to the idea of moving towards reuse of a 
> standard Java event API
> post 1.1 if it can be cleanly and easily extended to do all 
> the things that ours
> can do. At the moment, though, for everyone except event 
> source implementors I
> think the learning curve is negligable, especialy if there is 
> previous knowledge
> of other event systems. We should probably aim to provide a
> Changeability->PropertyChangeEvent bridge for people wanting 
> to easily build
> GUIs (hours in the day ... volunteers?).
> 
> I probably haven't said anything new here (and used more 
> words than anybody
> else). The current state of affairs is a first-attempt at 
> implementing this kind
> of thing, so there is still considerable room for change. 
> After all, the code
> must primarily be usable rather than an exercise in design. I 
> almost certainly
> don't read enough APIs to know how other projects handle 
> this, there is probably
> a better way.
> 
> All the best,
> 
> Matthew
>