Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaBeans alternatives?

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<String> name = new Property();
}

I am a web developer mostly, so it needs JPA and Wicket support.

Help me off the javabean train!

like image 965
SamBeran Avatar asked Jan 13 '09 23:01

SamBeran


People also ask

Is EJB and JavaBean are same?

A JavaBean is a Java class that encapsulates multiple objects and conforms to certain conventions. JavaBeans are used mainly for client-side development. An enterprise bean (EJB) is a Java class imbued with specific server-side capabilities. Enterprise beans are used in large-scale business applications and systems.

What is the use of JavaBeans?

JavaBeans is a portable, platform-independent model written in Java Programming Language. Its components are referred to as beans. In simple terms, JavaBeans are classes which encapsulate several objects into a single object. It helps in accessing these object from multiple places.

Why is it called JavaBean?

actually when they were developing java , the developers consumed so much of coffee so they made it as their symbol. and then so as the beans are small parts of the coding they named it as beans corresponding to small coffee beans.

What is spring bean and is it the same as JavaBean?

Spring bean is managed by Spring IOC, Java Bean is not. Java Bean is always serializable, Spring Bean doesn't need to. Java Bean must have a default no-arg constructor, Spring Bean doesn't need to. A Java object can be a JavaBean, a POJO and a Spring bean all at the same time.


2 Answers

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<T> {
    public final String name;
    T value;
    private final PropertyChangeSupport support;

    public static <T> Property<T> newInstance(String name, T value, 
                                              PropertyChangeSupport support) {
        return new Property<T>(name, value, support);
    }

    public static <T> Property<T> 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<String> name = Property.newInstance("name", "", support);
    public final Property<Integer> 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.

like image 62
Dave Ray Avatar answered Oct 02 '22 05:10

Dave Ray


Check out my Bean annotations at

http://code.google.com/p/javadude/wiki/Annotations

Basically you do things like:

@Bean(
  properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
  }
)
public class Person extends PersonGen {}

rather than defining all those extra get/set etc methods yourself.

There are other attributes to define equals/hashCode, observers, delegates, mixins, etc.

It's a set of annotations and an annotation processor that runs in eclipse or in a command-line build (in ant for example). The processor generates a superclass to contain all the generated code (annotation processors cannot change the class containing the annotations, btw)

like image 38
Scott Stanchfield Avatar answered Oct 02 '22 05:10

Scott Stanchfield