Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Practically Groovy: Reduce code noise with Groovy

Find out how Groovy frees you to focus on the important aspects of coding

Scott Hickey (shickey@bass-inc.com), Consultant, Bass and Associates, Inc.
Scott Hickey is a Java consultant with Bass and Associates. He has been developing software for over 20 years and working with Java since 1998. He is also the lead developer for the Groovy Eclipse Plugin.

Summary:  Groovy's concise syntax frees developers from typical Java™ constructs that are required for code compilation but don't facilitate expressing what a program is really trying to accomplish. In this revival of the Practically Groovy series, Groovy developer and guest columnist J. Scott Hickey walks you through a series of comparisons between normal Java code and the same Groovy code to show you how this exciting language frees you to focus on the important aspects of coding.

View more content in this series

Date:  19 Sep 2006
Level:  Intermediate
Also available in:   Chinese  Russian  Japanese

Activity:  1605 views
Comments:  

Often, programmers turn to languages like Groovy for building quick utilities, rapidly writing test code, and even for creating components that make up larger Java applications because of Groovy's innate ability to remove much of the noise and complexity that accompanies typical Java-based systems. Groovy's concise, yet flexible syntax frees developers from normal Java constructs that are required for code compilation but don't necessarily help express what the program is really trying to accomplish. What's more, Groovy's relaxed typing removes perceived code complexity through the reduction of interfaces and super classes, which are required in normal Java applications to support common behavior among distinct concrete types.

About this series

The key to incorporating any tool into your development practice is knowing when to use it and when to leave it in the box. Scripting (or dynamic) languages can be an extremely powerful addition to your toolkit, but only when applied properly to appropriate scenarios. To that end, Practically Groovy is a series of articles dedicated to exploring the practical uses of Groovy, and teaching you when and how to apply them successfully.

As an example of how Groovy can reduce the associated noise of a plain old Java application, I'll use sample code from Bruce Tate and Justin Ghetland's Spring: A Developer's Notebook (Resources), which introduces Inversion of Control with Spring. As I review each Java example, I'll make a comparison to corresponding Groovy source that is functionally equivalent, and I think you'll see quite quickly how much clearer Groovy makes application code by reducing various aspects of Java programming, which are noisy and don't necessarily convey an application's behavior.

The sound of Groovy

In the first chapter of Bruce and Justin's book, they create a simple bike store application, which has four different classes. First, I'll show you a simple JavaBean class named Bike, which represents a bicycle in stock. Then, I'll examine a bike store type, dubbed RentABike, which contains a collection of Bikes. There is also a class for displaying a list of bikes, aptly named CommandLineView, which depends on the RentABike type. Finally, there is a class responsible for assembling the parts to create a working application, which utilizes Spring to deliver the CommandLineView class fully configured with the RentABike type -- free of hardwiring.

Pipe down JavaBean!

The class that represents a bike, found in Listing 1, is implemented as a simple JavaBean in normal Java code and is representative of hundreds of classes that Java developers have probably written. Typically, there is nothing special about JavaBeans -- properties are declared as private and are accessed through public getters and setters.


Listing 1. A Bike JavaBean in Java code
    
import java.math.BigDecimal;
   
public class Bike {
   private String manufacturer;
   private String model;
   private int frame;
   private String serialNo;
   private double weight;
   private String status;
   private BigDecimal cost;
   
   public Bike(String manufacturer, String model, int frame, 
     String serialNo, double weight, String status) {
      this.manufacturer = manufacturer;
      this.model = model;
      this.frame = frame;
      this.serialNo = serialNo;
      this.weight = weight;
      this.status = status;
   }

   public String toString() {
      return "com.springbook.Bike : " +
            "manufacturer -- " + manufacturer +
            "\n: model -- " + model +
            "\n: frame -- " + frame +
            "\n: serialNo -- " + serialNo +
            "\n: weight -- " + weight +
            "\n: status -- " + status +
            ".\n"; }

   public String getManufacturer() { return manufacturer; }

   public void setManufacturer(String manufacturer) {
      this.manufacturer = manufacturer;
   }

   public String getModel() { return model; }

   public void setModel(String model) { this.model = model; }

   public int getFrame() { return frame; }

   public void setFrame(int frame) { this.frame = frame; }

   public String getSerialNo() { return serialNo; }

   public void setSerialNo(String serialNo) { this.serialNo = serialNo; }

   public double getWeight() { return weight; }

   public void setWeight(double weight) { this.weight = weight; }

   public String getStatus() { return status; }

   public void setStatus(String status) { this.status = status; }
   
   public BigDecimal getCost() { return cost; }
   
   public void setCost(BigDecimal cost) {
     this.cost = cost.setScale(3,BigDecimal.ROUND_HALF_UP);
   }
   
}  

Whew! Listing 1 is a small example with only one constructor and six properties, but the code comes close to filling the entire page of a browser! Listing 2 shows the same JavaBean defined in Groovy:


Listing 2. A Bike GroovyBean
  
class Bike {
  
  String manufacturer
  String model
  Integer frame
  String serialNo
  Double weight
  String status
  BigDecimal cost
  
  public void setCost(BigDecimal newCost) {
    cost = newCost.setScale(3, BigDecimal.ROUND_HALF_UP)
  }
  
  
  public String toString() {
    return """Bike:
         manufacturer --  ${manufacturer} 
         model -- ${model}
         frame -- ${frame} 
         serialNo -- ${serialNo}  
      """
  }
}

Which one do you think is less noisy?

The Groovy version is much, much smaller because Groovy's default property semantics automatically define a private field with public accessors and mutators. For example, the property model from above now has the equivalent of a getModel() and setModel() method automatically defined. As you can see, this technique has the benefit of eliminating two hand-coded methods per property defined in a type! This also illustrates a recurring theme in Groovy: Make common coding conventions simple.

Groovy's updated property semantics

The latest release of Groovy, JSR-06, simplified Groovy's property semantics. Prior to this release, properties were specified with a @Property annotation preceding the variable declaration. This notation, however, is no longer required. With JSR-06, just by specifying a type and variable name, a private property with a public getter and setter will be generated. The def keyword can also be used instead of a specific type.

What's more, with Groovy, the default functionality of a class is expressed more concisely compared to what must be coded explicitly in normal Java code (like in Listing 1). When there is a need to do something special with a constructor or a getter or setter, Groovy really shines because the interesting behavior becomes immediately obvious, just by glancing at the code! For example, it's easy to see in Listing 2 that the setCost() method is going to scale the cost property to three decimal places.

Compare this unobtrusive Groovy code to the Java source in Listing 1. The first time you read the listing, did you notice that the setCost() method had special functionality sprinkled in it? Unless you looked carefully, it's pretty easy to overlook!

A Groovy hearing test

The test case for the Bike class in Listing 3 demonstrates the use of the automatically generated accessor. Also, in the spirit of further simplification for common programming tasks, the test case also uses the more convenient Groovy dot property name notation for accessing properties. Accordingly, I am able to reference the model property either through the getModel() method or more concisely as b.model.


Listing 3. A Bike Test Case in Groovy
  
class BikeTest extends GroovyTestCase {
  void testBike() {
    // Groovy way to initialize a new object
    def b = new Bike(manufacturer:"Shimano", model:"Roadmaster")
  
    // explicitly call the default accessors
    assert b.getManufacturer() == "Shimano"
    assert b.getModel() == "Roadmaster"
  
    // Groovier way to invoke accessors
    assert b.model == "Roadmaster"
    assert b.manufacturer == "Shimano"
  }
}

Also notice that in the Groovy examples above, I didn't have to define a constructor that accepts all six properties like the Java constructor defined in Listing 1. Additionally, I didn't have to create yet another constructor that only takes two arguments to support my test case -- Groovy's semantics for setting object properties during object creation removes the need for those noisy, annoying constructors with various argument combinations that do little but initialize variables.

Groovy and IDEs

IDEs such as Eclipse make it easy to automatically create getters and setters. These tools also make it easy to extract interfaces from concrete classes to facilitate refactoring. I'd argue, however, that code is read more often than it is written. Unfortunately, developers still have to wade through generated code and source files to discern what a program is really doing. With the high quality of Java tooling available, it is debatable whether or not there is a huge savings in the keystrokes to create the Groovy source, but at a glance, you can see that the Groovy code is more concise, easier to decipher, and less complex. In practice, this is a powerful advantage across the scope of applications that have hundreds of classes and thousands of lines of code.

Hushed complexity

In the previous section, the Bike GroovyBean took advantage of Groovy's property and constructor semantics to remove noise from the source code. In this section, the Groovy version of the bike store will also benefit from additional noise-reduction features such as duck-typing for polymorphism, collection class enhancements, and operator overloading.

Grooving with polymorphism

In the Java bike application, an interface, dubbed RentABike, is used to define the public methods supported by the bike store. As demonstrated in Listing 4, RentABike defines some simple methods for returning a single Bike or a list of all the Bikes in the store:


Listing 4. A RentABike interface defined in Java
  
import java.util.List;

public interface RentABike {
   List getBikes();
   Bike getBike(String serialNo);
   void setStoreName(String name);
   String getStoreName();
}

This interface enables polymorphic behavior and thus provides flexibility in two important scenarios. First, if there is a decision to change the implementation, say, from an ArrayList to a database, the rest of the application is insulated from that change. Also, using interfaces provides flexibility during unit testing. For example, if there is a decision to use a database for the application, you can easily create a mock implementation of the type which doesn't depend on a live database.

Listing 5 shows a plain old Java implementation of the RentABike interface using an ArrayList to store instances of the Bike class:


Listing 5. A Java implementation of the RentABike interface
    
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListRentABike implements RentABike {
   private String storeName;
   final List bikes = new ArrayList();

   public void setStoreName(String name) {
      this.storeName = name;
   }

   public String getStoreName() {
      return storeName;
   }

   public ArrayListRentABike(String storeName) {
      this.storeName = storeName;
      bikes.add(new Bike("Shimano", "Roadmaster", 20, "11111", 15, "Fair"));
      bikes.add(new Bike("Cannondale", "F2000 XTR", 18, "22222",12, "Excellent"));
      bikes.add(new Bike("Trek","6000", 19, "33333", 12.4,"Fair"));
   }

   public String toString() { return "com.springbook.RentABike: " + storeName; }

   public List getBikes() { return bikes; }

   public Bike getBike(String serialNo) {
      Iterator iter = bikes.iterator();
      while(iter.hasNext()) {
         Bike bike = (Bike)iter.next();
         if(serialNo.equals(bike.getSerialNo())) return bike;

      }
      return null;
   }
}

Now compare the Java code in Listings 4 and 5 to the Groovy code in Listing 6. The Groovy version cleverly obviates the need for the RentABike interface!


Listing 6. Groovy's ArrayListRentABike implementation
  
public class ArrayListRentABike {
  String storeName
  List bikes = []
  public ArrayListRentABike(){		
    // add new instances of Bike using Groovy's initializer syntax
    bikes << new Bike(manufacturer:"Shimano", model:"Roadmaster",
      frame: 20, serialNo:"11111", weight:15,	status:"Fair")
    bikes << new Bike(manufacturer:"Cannondale", model:"F2000",
      frame: 18, serialNo:"22222", weight:12,	status:"Excellent")
    bikes << new Bike(manufacturer:"Trek", model:"6000",
      frame: 19, serialNo:"33333", weight:12.4,	status:"Fair")
  }

  // Groovy returns the last value if no return statement is specified
  public String toString() { "Store Name:=" + storeName }

  // Find a bike by the serial number
  def getBike(serialNo) { bikes.find{it.serialNo == serialNo} }

}

Groovy, like other dynamic languages such as Smalltalk or Ruby, supports polymorphism with "duck typing" -- at runtime, if an object acts like a duck, it is treated like a duck, thus supporting polymorphism without interfaces. With the Groovy ArrayListRentABike implementation, not only are there fewer lines of code, complexity has been reduced by having one less module to create and maintain. That's some serious noise reduction!

In addition to duck typing, the default property semantics in Listing 6 concisely define two ordinary properties, storeName and bikes, as having getters and setters. This is the same benefit as was illustrated in the JavaBean-GroovyBean comparison from Listings 1 and 2. Furthermore, Listing 6 also illustrates another Groovy feature that quells code noise -- operator overloading. Notice how you can use the << operator instead of the add() method. Code readability is improved by removing one level of nested parentheses. This is another one of the many seemingly small features in Groovy that facilitates code readability through the reduction of noise.

Euphonic collections a la Groovy

The use of closures with methods such as each and find simplify the most common collection tasks like looping and searching. Compare the Java version of getBike() in Listing 5 with the Groovy version in Listing 6. In Groovy, it's instantly apparent that I am finding a Bike by its serial number. In the same Java version, defining an Iterator and casting the next item in the list is noise that hinders the understanding of what the application is really doing, which is finding a bike.

Transparent code

The duck-typing and property semantics in Groovy help remove noise by reducing the number of source lines of code; however, you can also remove noise by adding transparency. In Listing 6, notice the way the new Bike objects are created in ArrayListRentABike's constructor. The Groovy name and value initializer syntax is a little more verbose than the Java version, but the additional code adds clarity -- it's immediately obvious which properties are initialized to which values. Compare that to the Java version in Listing 5. Without looking back at the Bike JavaBean source, can you remember which parameter is the frame and which is the weight for new Bike("Shimano", "Roadmaster", 20, "11111", 15, "Fair")? I just wrote it and I can't!


A smaller, groovier bike store view

So far, I've compared the Bike and bike store types in both Java and Groovy. Now it's time to take a closer look at the bike store view. In Listing 7, the view class has one property, rentaBike, which references the RentABike interface and demonstrates the Java version of polymorphism in action. Because Java requires a declared type for all class properties, instead of coding to a specific implementation, I code to an interface, which insulates this class from changes to a RentABike implementation. This is good, solid Java programming practice.


Listing 7. The Java version of the bike store view
  
public class CommandLineView {
   private RentABike rentaBike;
   
   public CommandLineView() {}

   public void setRentaBike(RentABike rentaBike) {
      this.rentaBike = rentaBike;
   }

   public RentABike getRentaBike() { return this.rentaBike; }

   public void printAllBikes() {
      System.out.println(rentaBike.toString());
      Iterator iter = rentaBike.getBikes().iterator();
      while(iter.hasNext()) {
         Bike bike = (Bike)iter.next();
         System.out.println(bike.toString());
      }
   }
}

Comparing the Java view in Listing 7 to the Groovy version in Listing 8, notice that I declare the rentaBike property with the def keyword. This is the duck-typing in action and just like the Java version, I'm practicing good software design because I haven't coupled my view to a specific implementation. But I also was able to achieve this decoupling without defining an interface.


Listing 8. Groovy's CommandLineView
  
public class CommandLineView {
  def rentaBike  // no interface or concrete type required, duck typing in action

  def printAllBikes() {
    println rentaBike
    rentaBike.bikes.each{ println it}  // no iterators or casting
  }
}

As with the Bike and bike store types, the Groovy's CommandLineView doesn't have the noise of an explicitly coded getter or setter for the RentABike property. Also, in the printAllBikes() method, I again take advantage of Groovy's powerful enhancements for collections by using each to print each bike found in the collection.


Using Spring for assembly

In the previous sections, we have seen how Groovy compares to Java in defining a bike, a bike store, and a bike store view. It is now time review how to assemble the whole application and use the command line view to display the list of bikes in inventory using Spring.

Factories of factories

In Java programming, once you have defined an interface, you can delegate responsibility for the creation of an actual implementation class to an object factory using the factory pattern. Using Spring as a factory is a great noise reducer and also happens to work well in both Groovy and Java, and in the final code examples, Spring is going to be responsible for creating an instance of the CommandLineView type in both Java and Groovy.

In Listing 9, Spring is configured to create and inject the ArrayList implementation of the bike store into CommandLineView before returning an instance of CommandLineView. This means that I don't have to reference the ArrayList implementation in either the Java or Groovy version of the command line view in Listings 7 and 8. In the Java version, the class being injected will almost always reference an interface, not the implementation. In Groovy, using the def keyword allows me to take advantage of duck-typing. In either case, Spring is now configured to deliver an instance of the bike store view fully configured with an instance of a bike store type!


Listing 9. The Spring configuration file
        
<beans>
    <bean id="rentaBike" class="ArrayListRentABike">
        <property name="storeName"><value>"Bruce's Bikes (spring bean)"</value></property>
    </bean>
    <bean id="commandLineView" class="CommandLineView">
        <property name="rentaBike"><ref bean="rentaBike"/></property>
    </bean>
</beans>
      

In Listings 10 and 11, the bike store assembler types create an instance of Spring's ClassPathXmlApplicationContext with the configuration file in Listing 9 and then request an instance of a bike store view:


Listing 10. Java version of calling Spring to create the bike store view
  
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class RentABikeAssembler {
   public static final void main(String[] args) {
      // Create a Spring application context object
      ClassPathXmlApplicationContext ctx = 
        new ClassPathXmlApplicationContext("RentABike-context.xml");
  
      // retrieve an object from Spring and cast to a specific type
      CommandLineView clv = (CommandLineView)ctx.getBean("commandLineView");
      
      clv.printAllBikes();
   }
}

Note in the Java version in Listing 10, the call to Spring for requesting an instance of the command line view requires a cast to an object type that supports the printAllBikes() method. In this case, the object coming out of Spring is being cast to CommandLineView.

With Groovy and its support for duck-typing, there is no casting involved. I just have to make sure that the class returned by Spring can respond to the appropriate method call, which is printAllBikes().


Listing 11. Groovy's version of Spring assembly
  
import org.springframework.context.support.ClassPathXmlApplicationContext

class RentABikeAssembler {
  public static final void main(String[] args) {
    // Create a Spring application context object
    def ctx = new ClassPathXmlApplicationContext("RentABike-context.xml")

    //Ask Spring for an instance of CommandLineView, with a 
    //Bike store implementation set by Spring
    def clv = ctx.getBean("commandLineView")
  
    //duck typing again
    clv.printAllBikes()
  }
}

As you can see in Listing 11, not only does duck-typing in Groovy help reduce noise by removing the need to declare interfaces to support auto-configuration of an object by Spring, it also simplifies using the fully configured bean once it is returned from the Spring container.


In harmony with Groovy

Hopefully, I've demonstrated the power of Groovy and how it can profoundly change the nature of source code. In contrast to the Java examples found above, Groovy code is smaller and easier to understand. Everyone from experienced Java architects to non-Java programmers can easily grasp the intention of the code. With Groovy and its support for dynamic typing, there are fewer files to manage, too. All in all, using Groovy removes a significant amount of noise that accompanies our typical Java programs. And that's a pleasant sound indeed!


Resources

Learn

Discuss

About the author

Scott Hickey is a Java consultant with Bass and Associates. He has been developing software for over 20 years and working with Java since 1998. He is also the lead developer for the Groovy Eclipse Plugin.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Open source
ArticleID=160594
ArticleTitle=Practically Groovy: Reduce code noise with Groovy
publish-date=09192006

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers