I hate the JavaBeans pattern with a passion that burns like the fire of a thousand suns. Why?
Verbose. It's 2009. I shouldn't have to write 7 LOC for a property. If they have event listeners then hold on to your hat.
No type-safe references. There is no type-safe way to reference a property. The whole point of Java is that it is type safe, and its most popular pattern is not at all typesafe.
What I would like is something like:
class Customer {
public Property name = new Property();
}
I am a web developer mostly, so it needs JPA and Wicket support.
Help me off the javabean train!
解决方案
I think you're pretty close with the declaration you have there (see below for a sketch). However, by using a non-beans approach, you'll probably lose support provided by most tools that assume the JavaBeans protocol is in effect. Please be kind. The code below is off the top of my head...
public class Property {
public final String name;
T value;
private final PropertyChangeSupport support;
public static Property newInstance(String name, T value,
PropertyChangeSupport support) {
return new Property(name, value, support);
}
public static Property newInstance(String name, T value) {
return newInstance(name, value, null);
}
public Property(String name, T value, PropertyChangeSupport support) {
this.name = name;
this.value = value;
this.support = support;
}
public T getValue() { return value; }
public void setValue(T value) {
T old = this.value;
this.value = value;
if(support != null)
support.firePropertyChange(name, old, this.value);
}
public String toString() { return value.toString(); }
}
and then go ahead and use it:
public class Customer {
private final PropertyChangeSupport support = new PropertyChangeSupport();
public final Property name = Property.newInstance("name", "", support);
public final Property age = Property.newInstance("age", 0, support);
... declare add/remove listenener ...
}
Customer c = new Customer();
c.name.setValue("Hyrum");
c.age.setValue(49);
System.out.println("%s : %s", c.name, c.age);
So, now declaring a property is a single line of code and property change support is included. I called the methods setValue() and getValue() so it would still look like a bean to code like Rhino and stuff, but for succinctness, you could add just get() and set(). The rest is left as an exercise for the reader:
Properly handle serialization
Handle null value checking
Maybe add a specializations for atomic types if you care about autoboxing overhead.
?? I'm sure there are more gotchas
Also note that you can subclass (usually as an anonymous class) and override setValue() to provide additional parameter checking.
I don't think you can really get away from "String references" since that's pretty much what reflection's all about.
Sadly though, in this day and age, this is still kind of like programming in assembly... Groovy, C#, etc, etc may still be a better choice, if you have a choice.