Thursday, February 17, 2011

What's a bean?

Java evolved from simply a language into an entire ecosystem of APIs and libraries and frameworks, more than any mere mortal can comprehend. You just cannot be an expert in all of them, as more are created every day, it seems, and the ones that were all the rage five years ago are now ground into dust beneath the wheels of what's newer and slicker. Some concepts still pervade a good number of them though, and one of them is the Java "bean".

There are many specific kinds of "beans", such as Enterprise Java Beans and MBeans and Persistent Entity Beans, but there is also just this general concept of a bean. Its origin is way back before the proliferation of APIs and frameworks, and the idea was that if you made a Java class just so, then tools, or other things that got a hold of your class, could find out things about it. A very simple set of conventions was determined, and if your class follows those conventions, then it's a bean.

Your class can be a bean and something else too. It's not a restrictive concept, like most Java concepts became for a while there. It really is only a set of conventions, a small one at that, which you can often adopt, and if you do, it can help you out.

Here are the conventions.

First, your class needs to have a public "no-arg" constructor; that is, it must be possible for code anywhere to make an instance of it by just saying new MyClass(). Fortunately, if you don't write a constructor for your class, Java makes a no-arg constructor for you. If you do write some other constructors, then you can just add this.
public MyClass() {}
Second, and this is kind of optional, your class needs to have properties. The idea behind a property is that you have a public getter and (if you like) a public setter method named similarly. Here:
public String getLastName() { return ln; }
public void setLastName (String n) { ln = n; }
The methods above define a read-write property called "lastName". Note that the property name starts with a lowercase letter. The getter takes no arguments and returns the property value, while the setter takes in a new value and returns nothing. If you want the property to be read-only, omit the setter.

The type of the property can be anything you like. One wrinkle: if it's boolean, use a different naming convention for the getter.
public boolean isAdult() { return (age >= 18); }
Inside your class, the property doesn't have to be represented by a field in a one-to-one relationship. Do whatever you like in there, but only expose publicly a named property of some type.

The third convention is ... well, I'm going to be a little ornery here and say that there aren't any more conventions you need to follow. The Wikipedia entry for JavaBean says your class should be serializable, which means that instances of it need to be able to be saved off and restored, but I don't think that's strictly required. (The entry itself says it "should" be serializable, so there.) And the official JavaBean spec has bits about beans exchanging events, but again I see that as optional if you want it.

So, in my ornery opinion, any Java class with a public no-arg constructor, and maybe with some properties, is a bean. There.

I claim this because by following these two simple conventions your classes can be wired into all sorts of neat things. The Apache Commons BeanUtils library is one of them, and while that library maybe isn't all that jazzy when used directly, it's the foundation for some really powerful Java technologies—just read the overview to see some examples.

Another powerful framework drawing from the bean concept is Spring, whose most fundamental offerings are all about creating and configuring objects for you as long as they are beans (well, often even if they aren't, but it really really likes beans).

I said above that "for a while there" Java concepts got restrictive. For example, the Java Servlet specification (which I still use all the time) says that, in order for a Java class to respond to HTTP requests, it has to extend a particular class HttpServlet and implement specific methods and use certain other classes and so on and so on. On its own, this is fine. But for a working Java developer, having to know this specialized set of classes for servlets, plus another for Enterprise Java Beans, and another for some other framework, well, it's a real pain. The community called out for a return to simplicity.

And so, frameworks like Spring and new language features like annotations arrived, and mercifully, the primary goals for these endeavors included "making your life easier so you can get your work done". One big way of making that happen was to leave the restrictive concepts behind and instead let you work with simple ones, like the humble bean. Then, after some hints and nudges, the heavy lifting would be done for you.

(If this sounds like you're encouraged to be lazy, then stop using Java and go work in assembly language. :) )

So, next time you're slapping some new classes together, think about making some of them beans along the way. It might not help you right away, but down the line that decision might pay off. Even the mere fact that the bean concept is a foundation for all these regions of the Java ecosystem should indicate that it's not a bad idea to adopt it for yourself.

No comments:

Post a Comment