US & Canada: 877 849 1850
International: +1 678 648 3113

Accelebrate Blog

ACCELERATED LEARNING, CELEBRATED RESULTS

That Which We Call A POGO, By Any Other Name

Spoiler alert: This article is about Plain Old Groovy Objects. Since they’re so intellectually simple, yet powerful, it’s also the source of many POGO-related non sequiturs. You’ve been warned.

Some History, Much of Which is Actually True

Deep in the mists of time when Java was shiny and new (circa 1996), Java added the “JavaBeans Specification” to the language. That was part of the migration from Java 1.00-A and 1.01 to the final JDK 1.1 APIs. If you’re really, really bored (why else are you reading this blog post?), you can still find the change history online at http://www.oracle.com/technetwork/java/javase/documentation/spec-141065.html. If you go there, you’ll notice that every mention of JavaBeans actually has a little ™ next to it because Microsoft got there first with COM for components, so you might as well get lawyers involved if you’re forced to make a pun (Java beans, get it?).

The JavaBeans spec is where we first started referring to getters and setters (or, in the obscure parlance of object-oriented programming, accessors and mutators, as if they have been exposed to gamma radiation or something) using the naming convention we’ve adopted ever since.

A Trivial JavaBean

public class MyBean {
    String name
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

JavaBeans were really intended to be a component architecture, so that you could assemble them into a program just by wiring them together. The idea was to purchase a library of third-party beans from some commercial provider, import them into a visual editing environment, and wire them together through their properties (using the aforementioned getters and setters) and code without ever really coding, which has always been a software manager’s dream.

Back in 1997 I even managed to convince my boss at the time to purchase the recommended editing environment, called Sun Java Workbench, for which I am profoundly sorry. Comparable IDEs at the time were Symantec’s Visual Cafe, IBM’s VisualAge for Java, and Borland’s Java IDE. It’s probably not a coincidence that not only do none of those IDEs exist anymore, neither do the companies that created them.

(Yeah, I said it! IBM and Symantec don’t exist anymore! Go ahead, prove me wrong!)

Sun Java Workbench was actually pretty cool. It had a pipe metaphor that you dragged your “beans” onto the visual page, and dragged pipes as lines from one bean’s output into another bean’s input. As I recall, the pipes could only go in rectangular directions, because, well, I have no idea, but it looked good.

I’d insert a picture here, but even Google’s Image Search couldn’t find one. It’s that obscure.

Getting back to the JavaBeans specification, it gave us a few interesting innovations:

  • the getter and setter conventions for properties
  • serialization, so the environment could save its state when you closed it
  • introspection, which we later called reflection
  • a required default, no-arg constructor, because of reflection
  • bound and constrained properties, property change listeners, and other event-driven mechanisms that we stopped caring about when web apps came along

The spec also defined java.beans.PropertyVetoException, one of my favorite exceptions because it sounded like it was involved in some real estate deal that went bad.

(Some of my other favorite exceptions were TooManyListenersException, which hopefully doesn’t happen during class, UnsupportedFlavorException, as in chocolate and vanilla are okay but strawberry is out, CloneNotSupportedException, which has all sorts of ethical quandaries, and the tragic MalformedURLException, please give generously. As a Connecticut resident, I can also assure you that the IllegalStateException refers to New York. My favorite subclass of java.lang.Error, btw, is the same as everybody else’s: ThreadDeath.)

Needless to say, the whole “let’s pretend to be Visual Basic” phase of Java didn’t work out, and the JavaBeans specification faded into obscurity.

The World Wide Web and Kinda, Sorta, JavaBeans

By 1998, nobody cared about poor JavaBeans any more, until suddenly everybody wanted to write web apps. (Let’s just pretend the dalliance into applets never happened, okay? I was there. IT NEVER HAPPENED.)

When Sun first proposed an architecture for web apps, they suggested a variation of Model-View-Controller they called “Model 1″:

  • The View was composed of JavaServer Pages (JSP) Pages (yes, that’s from the Department of Redundancy Department, but that’s what they called them in the official docs)
  • The Controllers were also JSP Pages (hard to believe, but true)
  • The Model was composed of, you guessed it, JavaBeans

The JavaBeans at the time were largely a way of getting the controller code out of the view layer and into classes. Even when Sun gave up and adopted Model 2, where the controllers were suddenly servlets, the JavaBeans were still part of the Model.

The problem was, in a web app nobody cared about bound and constrained properties or property change listeners, vetoable or otherwise. JavaBeans were just dumb data structures with an occasional method to do business logic, needed because nobody had thought of services yet.

In other words, the JavaBeans everybody was using weren’t really JavaBeans, and even pedants finally got tired of saying, “they’re JavaBeans but not by the spec”, so another term was needed.

Thus was born the POJO.

The POJO, Java’s Gift to Massive Verbosity

According to the Wikipedia article (https://en.wikipedia.org/wiki/Plain_Old_Java_Object), the term POJO for Plain Old Java Object came from Martin Fowler, Rebecca Parsons, and Josh MacKenzie in September 2000.

The relevant quote is: “We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it’s caught on very nicely.”

Go figure. POJOs are just Java classes, and since there’s no specification, they can be defined however you want. In practice, though, they have getters and setters that follow the naming convention and pretty much nothing else. Here is one in all its glory:

A true POJO

import java.util.Date;
public class JavaTask {
    private String name;
    private int priority;
    private Date startDate;
    private Date endDate;
    private boolean completed;
 
    public JavaTask() {
        // default constructor
    }

    public JavaTask(String name, int priority, Date start,
        Date end, boolean completed) {
        this.name = name;
        this.priority = priority;
        this.startDate = start;
        this.endDate = end;
        this.completed = completed;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setPriority(int priority) {
        this.priority = priority;
    }
    public int getPriority() {
        return priority;
    }
    public void setStartDate(Date start) {
        this.startDate = start;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setEndDate(Date end) {
        this.endDate = end;
    }
    public Date getEndDate() {
        return endDate;
    }
    public void setCompleted(boolean completed) {
        this.completed = completed;
    }
    public boolean isCompleted() {
        return completed;
    }
    @Override
    public String toString() {
        return "JavaTask{" +
               "name='" + name + '\'' +
               ", priority=" + priority +
               ", startDate=" + startDate +
               ", endDate=" + endDate +
               ", completed=" + completed +
               '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        JavaTask javaTask = (JavaTask) o;

        if (completed != javaTask.completed) return false;
        if (priority != javaTask.priority) return false;
        if (endDate != null ? !endDate.equals(javaTask.endDate) :
            javaTask.endDate != null) return false;
        if (name != null ? !name.equals(javaTask.name) :
            javaTask.name != null) return false;
        if (startDate != null ? !startDate.equals(javaTask.startDate) :
            javaTask.startDate != null) return false;

        return true;
     }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + priority;
        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
        result = 31 * result + (completed ? 1 : 0);
        return result;
    }
}

That’s nearly 100 lines of code just to wrap five attributes. If you’re going to write all that code, even if it’s generated by your IDE, you might as well write a test, too. Here’s a test for the JavaTask class, implemented in Groovy.

The JavaTaskSpec class

class JavaTaskSpec extends spock.lang.Specification {
    Date now = new Date()
    JavaTask t = new JavaTask(name: 'name', priority: 3,
        startDate: now, endDate: now + 1, completed: true)

    def 'get and set name work'() {
        when:
        t.name = 'other'
        then:
        t.name == 'other'
    }

    def 'get and set priority work'() {
        when:
        t.priority = 4
        then:
        t.priority == 4
    }

    def 'get and set startDate work'() {
        when:
        t.startDate = new Date() + 1
        then:
        (t.startDate - (new Date() + 1)) < 1
    }

    def 'get and set endDate work'() {
        when:
        t.endDate = new Date() + 2
        then:
        (t.endDate - (new Date() + 2)).abs() < 1
    }

    def 'is and set completed work'() {
        when:
        t.completed = false
        then:
        !t.completed
    }

    def 'toString method works'() {
        given:
        String expected = "JavaTask{name='${t.name}', " +
            "priority=${t.priority}, startDate=$now, " +
            "endDate=${now + 1}, completed=${t.completed}}"
        expect:
        t.toString() == expected
    }

    def 'equals method is correct'() {
        given:
        JavaTask t1 = new JavaTask(name: t.name, priority: t.priority,
        startDate: t.startDate, endDate: t.endDate,
        completed: t.completed)
        expect:
        t == t1
    }

    def 'hashCode method is correct'() {
        given:
        JavaTask t1 = new JavaTask(name: t.name, priority: t.priority,
        startDate: t.startDate, endDate: t.endDate,
        completed: t.completed)

        expect
        t.hashCode() == t1.hashCode()
    }
}

This is a test written using the Spock testing framework (http://spockframework.org), which is based on ideas from JUnit, but is superior to JUnit in pretty much every way possible. The test has to be written in Groovy, but the class being tested can be in Groovy, Java, or any other JVM-based language.

Spock tests are readable even to people who don’t know the framework. Each test method has a descriptive name surrounded by quotes. The body of the test contains blocks like given, expect, when, and then. Each statement in the then and expect blocks is evaluated according to the Groovy Truth, which means non-null references are true, non-zero numbers are true, non-empty collections are true, non-empty strings are true, the boolean value true is true, and so on. Spock is a logical (sorry) framework for enterprise (sorry again) testing.[1]

Spock allows you to test well and prosper (sorry yet again). It has been, and always shall be, your friendly testing framework (okay, no more, I’m done).

The point is, now I have a test, so now I am free to refactor my POJO into a POGO.

POGOs

Try googling the word “pogo” some time. I figured all I’d find was something about pogo sticks, but boy was I in for a surprise. Here’s just a sample:

The list goes on and on. I had no idea. Of course the one I mean is Plain Old Groovy Objects.

Since this post has already gone way beyond any reasonable expectations, let me just present the defining characteristics of POGOs[2]:

Getters and Setters

Any attribute that is not declared public or private has auto-generated getters and setters.

Constructors

POGOs[3] have a default, no-arg constructor, plus a “map-based” constructor that allows you to set attributes using a colon notation.

@Canonical

The @Canonical Abstract Syntax Tree (AST) transformation, when applied to a POGO[4], generates a toStringmethod, an equals method, a hashCode method, and a tuple (consecutive arguments) constructor based on the attributes of the class. Whoa. In other words, here’s the complete POGO equivalent to the POJO given earlier:

import groovy.transform.Canonical

@Canonical
class GroovyTask {
    String name
    int priority
    Date startDate
    Date endDate
    boolean completed
}

That’s it. Seriously, that’s the whole class. The same Spock test from before passes here[5].

Which would you rather write, the 100-line monstrosity from Java, or the 10-line (including the import statement) Groovy version? Sure, the IDE generated most of the Java code, but in Groovy all that code comes for free, and any code not present won’t develop bugs later. The Groovy attitude is that if the IDE can do it, why can’t the compiler? Even better, you can read this one, without swimming through all that generated code, and it works with the rest of your Java code simply by compiling it. So please consider using POGOs for all your mapped data.[6]

Hopefully this gives you an idea of what kind of productivity gains you can get by adding Groovy to your Java projects.

For more details, check out the book Making Java Groovy (http://manning.com/kousen). Oh, and Accelebrate offers training courses in Groovy (https://www.accelebrate.com/training/groovy), Grails (https://www.accelebrate.com/training/groovy-grails), and even Gradle (https://www.accelebrate.com/training/gradle), all of which are awesome.

Respectfully submitted by Ken Kousen <ken.kousen@kousenit.com>, who teaches this stuff.


1. The ‘enterprise’ thing was just a joke — it’s a unit testing framework like any other.
2. Remember, I mean Plain Old Groovy Objects, not Pogo Linux, http://www.pogolinux.com
3. That’s Plain Old Groovy Objects, not the Curious George game Pogo-A-Gogo from PBS Kids
4. By that I mean Plain Old Groovy Objects, not pogo, the “readable, DSL friendly programming language that compiles to JavaScript.” https://www.npmjs.org/package/pogo
5. Almost. The generated toString output is formatted somewhat differently, but that’s an easy modification
6. Okay, one more. Shouldn’t Data (http://en.memory-alpha.org/wiki/Data) run on Android? Hey, I just got a new Android phone! It even has unlimited Data!

Categories: Java Articles
Tags: , , ,

5 Responses to "That Which We Call A POGO, By Any Other Name"

Leave a Reply to Paco Zarate Cancel reply

Your email address will not be published. Required fields are marked *

Your email address will not be published. Required fields are marked *

*



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Please contact us for GSA pricing.
Contract #GS-35F-0307T

Please see our complete list of
Microsoft Official Courses