Wednesday, October 1, 2008

What Makes Java Objects Plain and Old?

Most people will tell you that Plain Old Java Objects, affectionately known as POJOs, are simply plain old goodness, similar to motherhood, when well planned, and apple pie, sans the hydrogenated lard laced with trans fat. When pressed to pin down what a POJO is though, you quickly realize it's a slippery fish. Mostly it is defined by describing what a POJO isn't. I.e., wikipedia defines it as follows:
... the term "POJO" is mainly used to denote a Java object which does not follow any of the (major) Java object models, conventions, or frameworks such as EJB.
You have to wonder why the "major" qualification is needed? It's okay to follow a "minor" Java object model? Perhaps the prevarication is to deal with this preceding statement:
A JavaBean is a POJO that is serializable, has a no-argument constructor, and allows access to properties using getter and setter methods.
Doesn't that contradict this "clarifying" statement in the definition:
All Java objects are POJOs, therefore ideally speaking a POJO is a Java object not bound by any restriction other than those forced by the Java Language Specification.
If everything is a POJO then non-POJOs clearly don't exist. After all, if a Java Bean is a POJO despite being required to comply to rules that are not forced by the language, e.g., a bean must be serializable and must have a no-arg constructor, then the boundary between plain oldness and the rest of the object universe is very ill defined indeed. Perhaps Java Beans are non-ideal POJOs. Does that make your brain feel as if it's about to burst like an overripe pumpkin?

Some people like to believe that they can sprinkle their POJOs with Java 5.0 annotations and still have POJOs, but BJ points out that this appears to be nonsense. He argues that although some annotations are okay, like @Override, other annotations that are part of a "major" Java object model, and are retained at runtime, are not okay. It's a reasonable argument.

Where does all this leave us? Unfortunately it leaves us in buzzword soup where the unwary are likely to be caught off guard. The important point that's become lost is that plain oldness is an aspect of the framework or context in which the objects are used, not an intrinsic property of objects themselves in isolation. Recall the statement that "all objects are POJOs." That's a recognition of the fact that there's nothing you can add to an object such that it's suddenly not a POJO. Similarly a pumpkin that's small and white, is still a pumpkin.

Consider that a framework that claims to support POJOs is claiming that it works for absolutely any Java object whatsoever without limitation. Conversely, if a framework requires something such that there exist objects it doesn't support, that framework doesn't support POJOs. By that reasoning, a framework that requires every instance to implement, for example, doesn't support POJOs. As such, a framework that requires Java Beans doesn't support POJOs, but that doesn't mean there's something wrong with Java Beans.

My reason for dwelling on this issue is frustration with "silly comments" that EMF objects aren't POJOs. Certainly EMF doesn't directly support POJOs (other than as data types) because modeled objects definitely are required to be EObjects. But any framework that claims to support POJOs yet doesn't support EMF's objects, because EMF objects aren't POJOs, is making deceptive claims. Most frameworks require something of the participants in order to be well-behaved players within that framework; from that perspective, most frameworks aren't POJO-based. For example, if you need objects that produce notification as they change, you need more than just POJOs. Generally I think most people need more than what POJO-based frameworks actually provide. While they will say they want something simple, like POJOs, what they ultimately end up actually needing is something rich and powerful. It's best to anticipate a client's ultimate needs rather than simply to pander to their stated needs.


Eric Rizzo said...

This last statement:

"It's best to anticipate a client's ultimate needs rather than simply to pander to their stated needs."

is a "dangerous" one if not qualified. Trying to anticipate ultimate needs is a slippery towards BDUF. Of course Ed's point about not just taking every stated need literally is valid. My point is just that the trick as a professional (consultant, framework designer, whatever) is to balance the desires of the client with the experience and knowledge that tells you they really will need something different.

Michael Scharf said...

I think POJO is a relative statement. Suppose I have a framework that requires that the objects I support have to follow some convention (implementing an interface or following some naming convention). In that context anything that does not follow my convention is a POJO.

Your objects might be POJOs for me and my objects might be POJOs for you. POJOness is a matter of perspective.....