Extensible Properties for the Java Language
Remi Forax is leading some research on hacking in properties into the JVM. Richard Bair's latest post has inspired me to write about how I think observable properties could be implemented.I would like properties to be extensible, so that all the generic boilerplate (not just get/set) can be applied:
public class Person {
private @Property(ObservableProperty.class) String surname;
}
...where ObservableProperty implements a chain-of-command interface for setting properties:
interface Property<B,T> {
/** the delegate holds the 'real' property that we're just decorating */
public void setDelegate(Property<B,T> delegate);
/** @param name the bean property name, such as surname */
public void setName(String name);
public T get(B bean);
public void set(B bean, T value);
}
... and ObservableProperty is implemented something like this:
public class ObservableProperty<B extends Observable,T> implements Property<B,T> {
private Property<B,T> delegate;
private String name;
public void setDelegate(Property<B,T> delegate) {
this.delegate = delegate;
}
public void setName(String name) {
this.name = name;
}
public T get(B bean) {
return delegate.get(bean);
}
public void set(B bean, T value) {
T old = delegate.get(bean);
delegate.set(bean, value);
firePropertyChange(bean.getListeners(), name, old, get(bean));
}
}
The real power of this approach is chaining decorators:
private @Property(ObservableProperty.class, NotNullProperty.class) String surname;
private @Property(ObservableProperty.class, EmailAddressProperty.class) String emailAddress;
private @Property(TransactionalProperty.class) long id;
This approach makes code better because it is declarative. We are telling the API what to do, not how to do it.