Posts filed under 'Patterns'

Thoughts about Builder Pattern

Recently i watched the recorded presentation "Effective Java Reloaded" from Joshua Bloch which he held at the JavaOne 2006. He stated that static factories and constructors share a problem when they have many optional parameters. For example if you want to construct an ID3Tag object where lets say title and artist are mandatory and album, albumTrack, comment, year, genre etc. are optional one solutions is to write following constructor:

JAVA:
  1. ID3Tag(String title, String artist, String album,
  2.   int albumTrack, String comment, String year,
  3.   and a lot more optional parameters).

Every time you want to create an ID3Tag object you have to fill in values for all arguments. Typically this ends up that only a small amount of the actual arguments are non "null" values.

Another possible solution is the "Telescoping signature pattern" where you have a constructor with lets say 16 parameters one with 15, 14, 13 and so on. But what if we want to set only the first and 14th parameter. Then you have to take the 14 parameter constructor and fill all parameters except the first with null values.

The "Builder pattern" is a better way to solve this problem. The idea behind the builder pattern is that you write a builder constructor which takes only the mandatory arguments. For ID3Tag this would be title and artist. For all optional parameters there is a corresponding setter in the builder. When you have set all optional parameters you actually build the object from the builder. For our example:

JAVA:
  1. ID3Tag u2 = new ID3Tag.Builder("Where the Streets have no name""U2").album("The Joshua Tree").comment("great song").build();

To make the above code working the following has to be implemented:

JAVA:
  1. class ID3Tag {
  2.   private String title;
  3.   private String artist;
  4.   private String album;
  5.   private int albumTrack;
  6.   private String comment;
  7.  
  8.   public static class Builder {
  9.     private ID3Tag id3tag;
  10.  
  11.     public Builder(String title, String artist) {
  12.       id3tag = new ID3Tag(title, artist);
  13.     }
  14.  
  15.     public Builder album(String val) {
  16.       id3tag.album = val;
  17.       return this;
  18.     }
  19.  
  20.     public Builder albumTrack(int val) {
  21.       id3tag.albumTrack = val;
  22.       return this;
  23.     }
  24.  
  25.     public Builder comment(String val) {
  26.       id3tag.comment = val;
  27.       return this;
  28.     }
  29.  
  30.     // ... a lot more optional parameters
  31.  
  32.     public ID3Tag build() {
  33.       return id3tag;
  34.     }
  35.   }
  36.  
  37.   private ID3Tag(String title, String artist) {
  38.     this.title = title;
  39.     this.artist = artist;
  40.   }
  41. }

The ID3Tag class has its own builder as a static nested class. This gives the builder access to the private fields (via an object reference) of the ID3Tag class. The public builder constructor takes all mandatory parameters and creates a new ID3Tag Object with the private constructor of the ID3Tag class. The ID3Tag object reference is stored in a private field variable.

All optional parameters can be set via setter. The implementation of these setters is straightforward they set the given value for the corresponding field of the ID3Tag class via the ID3Tag reference variable in the builder. Each of these setters returns the builder object itself to allow cascading setting of optional parameters like '.album("The Joshua Tree").comment("great song")...'. Finally the public build method simply returns the stored ID3Tag object reference.

It's that simple as that. I think its a very useful pattern when you have to construct an object with a lot of optional parameters.

11 comments January 10th, 2007


Calendar

August 2008
M T W T F S S
« Jun    
 123
45678910
11121314151617
18192021222324
25262728293031

Posts by Month

Posts by Category