Groovy hip tip: to use or not to use setters and getters

In Groovy, if you define a hip object with properties, you can access them directly; that is, you don’t have to define the bogue old-style setters and getters that we were all taught to do back in the day with Java. For example, imagine a simple object defined in Groovy like so:

class Loan {
 def balance
 def term
 def rate
}

If you’d like to directly set the value of balance, for example, you could write

def loan = new Loan()
loan.balance = 30000

Note how the property was accessed directly as if it were public, but in fact, it’s private as the following copacetic test demonstrates:

import java.lang.reflect.Modifier
import groovy.util.GroovyTestCase

class LoanTest extends GroovyTestCase{
 void testLoanBalanceModifier(){
  def loan = new Loan()
  loan.balance = 30000
  assertEquals(30000, loan.balance)

  def field = Loan.class.getDeclaredField("balance")
  assertEquals(true, Modifier.isPrivate(field.modifiers))
 }
}

What’s more, even if you do define a setter, you don’t actually have to call it — Groovy will do that for you. For example, I can add the following setter method to the Loan object like so:

class Loan {
 def balance
 def term
 def rate

 void setRate(rate){
  if(rate > 0.99){
   this.rate = rate/100
  }else{
   this.rate = rate
  }
 }
}

And the following tests prove that under the covers, Groovy leveraged the setter properly, even though I don’t actually call the setter directly:

import groovy.util.GroovyTestCase

class AnotherLoanTest extends GroovyTestCase{
 void testLoanRate(){
  def loan = new Loan()
  loan.rate = 3
  assertEquals(0.03, loan.rate)
 }

 void testLoanRateAgain(){
  def loan = new Loan()
  loan.rate = 0.03
  assertEquals(0.03, loan.rate)
 }
}

This handy no-setter (or no-getter) syntax also works with plain old Java objects; that is, if you have a Java object that has private properties and setters and getters for accessing them, you can still directly access them Groovy-style. For instance, here is the same Loan object defined in Java:

import java.math.BigDecimal;

public class Loan {
 private BigDecimal balance;
 private int term;
 private float rate;

 public BigDecimal getBalance() {
  return balance;
 }
 public void setBalance(BigDecimal balance) {
  this.balance = balance;
 }
 //...all other setters and getters left out of example
}

As the below test shows, when using this Java object in Groovy, you can omit invoking setBalance for example:

void testLoan(){
 def loan = new org.disco.Loan() //java object
 loan.balance = 30000
 assertEquals(30000, loan.balance)
}

In fact, like before with the Groovy defined Loan, Groovy will invoke the getter or setter for that property defined in the Java class.

Clearly, the ability to seemingly access properties cuts down on the amount of code one must write; plus, the perceived safety and encapsulation that these methods provide is still present. Not bad, eh baby?

Looking to spin up Continuous Integration quickly? Check out www.ciinabox.com.