Groovy: POGOs

July 04, 2015

Only basic technical knowledge assumed.

Every well respected Groovy blogger must write about how awesome POGOs(Plain Old Groovy Objects) are. I am not a well respected Groovy blogger by any means, but I’m going to write about it anyway.

public class MyObject {
    private String myString;
    public String getMyString(){ return myString; }
    public void setMyString(String newMyString){ myString = newMyString; }

I think most of us agree that that’s about as minimalistic as a one-property POJO gets. Let me introduce the equivalent POGO:

class MyObject { String myString }

I’m serious. That’s it. Including the MyObject.groovy file name, that’s 35+15 = 50 characters!

How does that work you say?

Dispelling the magic

The forces at play here are:

  1. Defaults:

    1. class is actually public class
    2. Fields are assumed private by default, not package-private (when was the last time you used that one, and not by accident?)
  2. Public getters are implicitly generated.
  3. Public setters are implicitly generated.

Addressing some common concerns

Some developers tend to get uncomfortable when they hear the above, and often ask something along the lines of:

  • Q: What if I want a package-private class/field/method etc.?

You’re a dying breed, but who am I to stop you

  • Q: What if I don’t want my field to be accessible?

Then explicitly make it private.*

  • Q: What if I want my own getter/setter?

Then make one. It will override the implicit ones.

  • Q: How can I use the getters and setters?

Like normally. Groovy is clever enough to do the camel casing for you. Or, you could join the dark side and use the built in overloaded operators. (See below)

Operator overloading

Groovy also provide what’s known as operator overloading. Essentially, this means editing the operators we (think we know and) love like =, == and . etc. Obviously this can be very dangerous if not done right, but Groovy comes with two great examples of why you’d might want to use these. These are related to the accessors and mutators. Taking the example above, you can access myString like so: myObject.myString and it will call the getter (don’t worry, it’s not public). Similarly, you can call the setter by doing something like myObject.myString = "Groovy". How intuitive is that!

*This is sufficient in most cases, however, there are some known bugs. At the time of writing, Groovy conveniently and unfortunately violates encapsulation. See GROOVY-3010.

Roger Guldbrandsen

Written by Roger Guldbrandsen.