Thursday, October 23, 2008

Is that a POJO or a NOJO?

The term "POJO" is widely used in the Java programming world, but is sometimes used to mean something more specific than what was originally intended.

Furthermore, such code (whether called POJO or not by its authors) is a style which I think would be useful to give a specific name to.

What's a POJO?

The original meaning of POJO was a plain old Java object - that is, an object that isn't tied to a framework (for example, having to implement specific interfaces). A concrete example of a non-POJO would be entity beans (from EJB).

Introducing NOJOs

NOJOs are (instances of) classes which define fields, setters and getters but no other methods. They are popular in enterprise Java code and I think deserve a specific term, to distinguish them from the rather general term POJO.

NOJO stands for "Non Object-oriented Java Object". Although it might sound "negative" it is merely intended to be accurate and have a catchy acronym.

What defines an object?

An "object" (in object-oriented programming) has identity, state and behaviour. A NOJO has identity and state. A function has behaviour but not state. An object has identity, state and behaviour.

Why do you need a term for NOJO?

In many programming languages, there is a language construct for NOJOs (or something very similar) - e.g. "struct" in C, or "record" in Pascal. In Java there isn't an equivalent language construct - so the term NOJO is intended to mean the use of a Java class to implement such a thing, to make it easier to talk about such code.

Are NOJOs a Good Thing?

Left as an exercise for the reader.

25 comments:

Ben Ketteridge said...

NOJO = DTO.

Ivan Moore said...

DTO means something more specific - the term DTO is to do with it's role not it's implementation. A DTO is a NOJO but the terms are not equivalent (things can be NOJOs without being DTOs).

Anonymous said...

A NOJO is not equivalent to a struct or record. It still has inheritance, dynamic dispatch and private data.

Nat Pryce said...

beza1e1: a NOJO is class that *doesn't* use those features. Or if it does use, for example, private data, just makes its fields directly accessible through getters and setters so that they might as well be public.

Anonymous said...

One thing people shouldn't need to do (but doesn't stop them doing it anyway) is mocking out NOJOs - surely this is pointless.

keithb said...

Nice distinction.

Jesper said...

What you call a NOJO is really a plain old Java Bean (not an EJB).

Ivan Moore said...

A lot of plain old Java Beans are NOJOs but they don't have to be.

Nat Pryce said...

It's not necessarily a Java Bean. There's more to the Java Bean spec than putting "get" and "set" at the start of method names.

(In fact, you can use any naming convention you want for Bean property accessors. Any framework that requires you to use the getX/setX convention should not use the term "bean" at all.)

Alex said...

Hello.

I think your post fails to explain why these objects are 'smelly'.

These objects end up usually in what Fowler calls the Anemic Domain Model.

This is bad because you have the over head of the domain model without its advantages since your service layers still have to do all the hard work, which isn't very different from procedural programming.

jherber said...

Just bite the bullet - Scala has "case" classes that let you NOJO=DTO in one line.

case class Book(title:String, isbn:ISBN, authors:List[String])

Scala also lets you use these in pattern matching (think switch statement on steroids).

book match {
case Book(_,ISBN(1234),_) => print("found specific book")
case Book(_,_,List("Thomas Paine"))=> print("makes sense")
case _ => print("fall through")
}

hierarchies of case classes can even be "sealed" so your pattern match statement fails to compile if you are missing a member of the hierarchy in your case match.

Instances of Scala case classes don't even need require "new" keyword.

var b = Book("Tales of the Pointy Haired Boss", ISBN(321), List("Cube Dweller"))

Hokey said...

i always used the term "data bucket," which is in direct comparison to function buckets (that appear to be all over in JSF and library helper classes).

Philip Schwarz said...

One way to look at NOJOs:

Premise: Getters and setters are evil
Fact: NOJOs simply consist of getters and setters
-------------------------------------------
Conclusion: NOJOs are evil

Who says that getters and setters are evil? To get started, read Holub's Why getter and setter methods are evil.

For more, see Holub's summary (from Holub on Patterns) of the basic issues around setters and getters:

* The maintainability of a program is inversely proportional to the amount of data that flows between objects.

* Exposing implementation harms maintainability. Make sure that the accessor or mutator really is required before you add it.

* Classes that directly model the system at the domain level, sometimes called business objects, hardly ever need accessors or mutators. You can think of the program as partitioned broadly into generic libraries that have to relax the no-getter/no-setter rule and domain-specific classes that should fully encapsulate their implementation. Getters and setters at this level are an indication that you didn't do enough up-front design work. In particular, you probably didn't do enough dynamic modeling.

* By keeping the design process in the problem ("business") domain as long as possible, you tend to design messaging systems that don't use getters and setters because statements such as "Get this" or "Set that" don't come up in the problem domain.

* The closer you get to the procedural boundary of an OO system (the database interface, the UI-construction classes, and so on), the harder it is to hide implementation. The judicious use of accessors and mutators has a place in the boundary layer.

* Completely generic libraries and classes also can't hide implementation completely so will alwats have accessors and mutators.

* Sometimes it's not worth the trouble to fully encapsulate the implementation. Think of trivial classes such as Point and Dimension.

Philip Schwarz said...

NOJOs...although you gave them a name that suggests that they are not as good as POJOs, you say you didn't intend the name to sound negative. Presumably this is because you don't agree that NOJOs are bad, or because you have not yet decided whether NOJOs are bad (since you ask whether they are a good thing).

Back in 1999, in Refactoring, Martin Fowler called this type of object a Data Class.

* Your definition: classes which define fields, setters and getters but no other methods.
* His definition: classes that have fields, getting and setting methods for the fields, and nothing else.

While the name 'Data Class' is much less pejorative than 'NOJOs', Fowler doesn't think that Data Classes are good: he classified them as a code smell. In his words:

Data classes are like children. They are okay as a starting point, but to participate as a grownup object, they need to take some responsibility.

While Data Classes are bad, they can sometimes be used for a good cause: one way to get rid of the smell of Data Clumps is by creating Data Classes. But Data Classes remain bad, and so once you have created them, you (in Fowler's words):

'get the opportunity to make a nice perfume. You can now look for cases of feature envy, which will suggest behavior that can be moved into your new classes. Before long these classes will be productive members of society'.

Ivan Moore said...

"Presumably this is because you don't agree that NOJOs are bad, or because you have not yet decided whether NOJOs are bad". I think NOJOs are horrible. What I want is a catchy term that makes it clear what someone is talking about. It is evident that some people write code that they call POJOs (or whatever) that are actually NOJOs, and would be more clearly described as such.

Philip Schwarz said...

btw... great post, I like the term NOJOs, a lot!

Leonardo VerĂ­ssimo said...

In portuguese, "nojo" means "disgust".

So, this acronym is a good name for something that should be avoided, if possible.

Developer Dude said...

Show me a class that extends java.lang.Object that doesn't have behavior.

They all come with equals(), hashCode() and a number of other methods with "behavior". If you can expect your class to be kept in a collection (and many are - especially POJO/NOJOs) then those methods, especially equals/hashCode, can be very important - but very few devs override them, much less implement them correctly.

Philip Schwarz said...

NOJOs: good or bad? For a more mature, less black and white view of NOJOs and [real] Objects, see 'Objects and Data Structures', a chapter in Robert Martin's new book: 'Clean Code'.

In it, he talks about the anti-symmetry between [real] Objects and Data Structures [NOJOs].

He also talks about 'hybrids', the 'unfortunate hybrid structures that are half object and half data structure', and which are 'the worst of both worlds'.

He also revisits the Law of Demeter in the light of this distinction between real Objects and NOJOs.

See the book for how he arrives at the following modern, practical, non-polarised conclusion:

In any given system we will sometimes want the flexibility to add new data types, and so we prefer [real] objects for that part of the system. Other times we will want the flexibility to add new behaviors, and so in that part of the system we prefer data types [NOJOs] and procedures. Good software developers understand these issues without prejudice and choose the approach that is best for the job at hand

Philip Schwarz said...

Ivan, you said: "What I want is a catchy term that makes it clear what someone is talking about."

In my view you have succeeded.

Jason Kilgrow said...

eh.....no behavior? really?

public void setStuff(String stuff)
{
this.stuff = stuff;
}

That isn't behavior? Sure it's simple behavior. It doesn't do much but set the instance property. But it's still behavior.

Would you be happier with:

public void setStuff(String stuff)
{
this.stuff = stuff.toUpperCase();
}

Would that be behavior? I really can't see the difference. Still simple. Still behavior.

I like the idea. I've just always called these types of objects "dumb beans". Because...well....they're kinda dumb. :)

Unknown said...

Who says that getters and setters are evil?

Surely SOLELY having getters and setters is the purest result of analysis. All of your state is perfectly decoupled and orthogonal such that the only behavioral changes are managed by simple setters and setters. Admitidly more complex getters will add the interesting behaviour..

Michael Mahemoff said...

This used to be called a value object. Often in the same context as a DTO, but unlike DTO, doesn't imply a role.

Anonymous said...

@robin @developerdude @jasonkilgrow LOL. You reinforce my belief that far fewer people should be in this industry. Thank you for my daily affirmation.

@mahemoff true but we all dropped Sun's meaning of the term Value Object in favour of http://www.martinfowler.com/bliki/ValueObject.html - which do have oodles of behaviour.

Anonymous said...

The same way a String is a container for characters which make sense together, a so-called NOJO is simply a container of information which make sense together. Pure data, no behavior.

The example of a book is a good one: you need to keep author name, publisher name, year of publication, ISBN and eventually something else in order to properly identify a book. No behavior associated to any piece of data. Pure data and that's all!

The so-called NOJO is simply a VO (value object). This is not a new concept. Why inventing another acronym to VO?

Actually, you don't even need getters and setters. You can provide direct access to all fields, which must be necessarily public. Why? Because getters and setters are primary designed to encapsulate behavior, which can be simply getting/setting a field or can be something like calling some business logic before/after getting/setting a field. Anyway, getters/setters where invented in order to encapsulate behavior. By definition, we don't have and we will never have any behavior associated to the aforementioned data; in order to make this behavior-free aspect of VOs crystal clear, we should never employ getters/setters. This is a matter of readability: if you find a setter you may think that some business logic is being called; then you have to jump to the setter declaration in order to figure out what is happening. On the other hand, a public field states immediately that you are simply storing data in it. Simple, crystal clear, explicit, fast.

Regards

Richard Gomes
http://www.jquantlib.org/index.php/User:RichardGomes
twitter: frgomes

JQuantlib is a Library for Quantitative Finance written in Java.
http://www.jquantlib.org/
twitter: jquantlib