Dienstag, 11. September 2012

Eclipse Plugin for creating Builders

I wrote a small Plugin for Eclipse that automatically can generates the builder-pattern code for a given class.

About the builder Pattern

The builder pattern is a design pattern for creating object instances. It is especially useful when dealing with classes which have a larger number of constructor arguments. For each constructor argument, the builder has a setter-like method. Instead of directly creating an instance of the class, an instance of the builder is created, and all required properties are set on the builder. Finally, the intrinsic instance can be created by calling the builder's build-method.


Instead of calling:

Person myPerson = new Foo("John", "Doe", new Date(), "secret");

one would call:

Person myPerson = PersonBuilder.newBuilder()
    .firstname("John")
    .lastname("Doe")
    .birthday(new Date())
    .password("secret")
    .build()


This allows you to instantiate immutable classes with the verbosity of having setter-methods.

Implementing such builders by hand can by annoying. That's where the plugin can help....

About The Plugin

It tried to make the plugin work with almost any java class (java-beans, immutable classes, classes with hidden constructor and static factory methods).
  • generates Builder pattern Code based on an existing java classes
  • works well with immutable classes
  • works with zero-argument constructors, constructors with an arbitrary number of arguments and static factory methods
  • also generates a buildUpon-method, that constructs a new builder and populates it with the values of a given entity
  • optionally can create "fluent setters" that allow chaining a sequence of calls to the builder
  • can put the builder in the same file (as a static nested class), or create the builder as top level class
  • can create ordinary setter-methods (setFoo(...)) or short setter methods (foo(...))

Example

Given this Java class:

  public class Person {   
    private String firstName;   
    private String lastName;   
    private Date dateOfBirth;   
    public Person(String first, String last, Date dateOfBirth) {   
       this.firstName = first;   
       this.lastName = last;   
       this.dateOfBirth = dateOfBirth;   
    }   
    public String getFirstName() {   
       return firstName;   
    }   
    public void setFirstName(String firstName) {   
       this.firstName = firstName;   
    }   
    [...]   
    (remaining methods stripped)  
 }  

Results in the following Builder:
 public class PersonBuilder {  
      private String firstName;  
      private String lastName;  
      private Date dateOfBirth;  
      public static PersonBuilder newBuilder() {   
           return new PersonBuilder();   
      }  
      public PersonBuilder firstName(String value) {  
           this.firstName = value;  
           return this;  
      }  
      public PersonBuilder lastName(String value) {  
           this.lastName = value;  
           return this;  
      }  
      public PersonBuilder dateOfBirth(Date value) {  
           this.dateOfBirth = value;  
           return this;  
      }  
      public Person build() {   
           return new Person(firstName, lastName, dateOfBirth);  
      }  
      public static PersonBuilder buildUpon(Person original) {  
           PersonBuilder builder = newBuilder();  
           builder.firstName(original.getFirstName());  
           builder.lastName(original.getLastName());  
           builder.dateOfBirth(original.getDateOfBirth());  
           return builder;  
      }  
 }  

Using the Plugin

In an editor with an opened java-file, right-click, select "source" -> "Generate Builder..."
(You can also right-click on a java source file in the package-explorer.)
















This will give you this wizard:
First Page oft new Builder Wizard

Second page of new Builder Wizard

A more Complex Example

The plugin can also generate builders for a classes that have no public constructors, for example java.util.Calendar. In this case, the plugin looks for factory-methods on the type (all static methods that return an instance of the class) and lets you pick such a method:


You can also include properties that are not part of the constructor, but set via ordinary setter-methods.

Installation

The Plugin was tested with Eclipse 3.6 (Helios) and 3.7. (Indigo). It may or may work with older and newer versions....

Download the two jar-files from here, and copy them to the "dropins"-folder of your eclipse-installation. Done!