Fluent Object Creation

Many posts have been written on this subject (overwhelmingly many) but I just wanted to contribute my two-cents and write a short post about how I use the Fluent Object Creation pattern or object builders in Java to instantiate Value Objects.
Value Objects are abstractions that are defined by their state (value) rather than their address in memory. Examples of value objects are things like money, a number, a coordinate, etc. They are used not to describe Business Objects but rather descriptions of concrete indivisible entities. Also, they make great candidates for adding them to collections and maps.

In Java, Value Objects should be declared final and provide no setter methods, basically making it’s state immutable after creation, this is a very important
 
requirement. Declaring them final makes them unable to serve as parent objects. This is done by design since value objects should model small and concrete entities. The reason being is that we should be able to create and compare multiple copies of these objects, which is always done by state not by reference. In addition, you should declare proper equals() and hashCode() methods to qualify for a proper value object. In C++, the same principles apply. In C++ you should make use of the Copy Constructor and overload the assignment and comparison operators. The Fluent Object Creation pattern makes value object instantiation elegant and clean. There are many benefits that can be gained by using fluent object creation as we will see shortly.

The end result of applying this pattern from the API user’s perspective will look like the following:

Money fiveEuros = new Money.Builder()
   .currency(Currency.EURO)
   .value(5.0L)
   .countryOfOrigin("Spain")
   .type("Coin")
   .reverse("Map of Europe")
   .obverse("Map of Spain")
   .addColor("Bronze")
   .addColor("Silver")
   .year("1880")
.build();

I think you would agree that this pattern flows a lot more smoother as opposed to this:

 Money fiveEuros = new Money();
fiveEuros.setCurrency(Currency.EURO);
fiveEuros.setValue(5.0L);
fiveEuros.countryOfOrigin("Spain");
fiveEuros.type("Coin");
fiveEuros.reverse("Map of Europe");
fiveEuros.obverse("Map of Spain");

List<String> colors = new ArrayList<String>();
for(String color: new String[] {"Bronze", "Silver"}) {
   colors.add(color);
}

fiveEuros.setColors(colors);
fiveEuros.setYear("1880");

Which seems broken and has lots of typing and repetition. This is an example of building a pretty big value object in my opinion, most of tend to be very small. Before we talk about the benefits of creating objects this way, let’s have a look at the structure of this pattern:

 public final class Money {
   
      private Long value;
      private String countryOfOrigin;     
      private Currency currency;
      private String type; 
      private String reverse;
      private String obverse;    
      private List<String> colors;
   private Date year;    
 
      private Money() {   }

     // -- getters, hashCode, equals -- //

     // Static inner Builder class
   public static class Builder {
        private Money _temp = new Money();
public Builder value(Long val) {
_temp.value = val;
return this;
}
public Builder countryOfOrigin(String countryOfOrigin) {
_temp.contryOfOrigin = countryOfOrigin;
         return this;
}
public Builder currency(Currency c) {
_temp.currency = c;
return this;
}
public Builder type(String t) {
_temp.type = t;
return this;
}
public Builder reverse(String r) {
_temp.reverse = r;
return this;
}


       public Builder obverse(String o) {
_temp.obverse = o;
return this;
}


public Builder addColor(String c) {
if(_temp.colors == null) {
              _temp.colors = new ArrayList<String>(); 
           }
           _temp.colors.add(c);
return this;
}

         public Builder year(String y) {
              if(y == null || y.isEmpty()) {
                  _temp.year = new Date();
              }
              else {
                  _temp.year = DateFormat.parse(y);
              }
return this;
}
public Money build() {
                // Validate object
               if(Strings.isNullOrEmpty(_temp.name) || _temp.currency == null) {
                  throw new IllegalArgumentException("Coin currency and value required");
               }
return _temp;
}
    }
}

This is also a matter of taste, but I prefer the static inner class approach. I like the canonical nature of referring to the builder as
Money.Builder. Also making it static is required since the builder instance needs to live independently of the enclosing class. I like this pattern because it has the following benefits:

  1. Greater object encapsulation: I can easily enforce object construction using builders by making the Money constructor private (this is just stylistic). This completely hides all of the intricacies of creating this object: list creation, date parsing, etc. From the user’s perspective, what we end up with is an object that is simple to instantiate. My illustration is a very simple one, but imagine more complex object graphs.
  2. Code readability: Using this pattern to create objects, makes unit tests and code very easy to read and follow.
  3. Less typing in the long run: Even though you have to add an extra builder method for every added attributes, the amount of typing you save in the long run makes it worth while.

Conclusion

Using the fluent creation pattern is more work up front, but the benefits of having it pays off at the end. It makes instantiating objects very elegant and clean. You don’t have to use it with Value Objects, most of the benefit of using Fluent Object Creation is when you need to build pretty complex object graphs, but I wanted to show that it can also suit small value objects.
 

Reference: Fluent Object Creation from our JCG partner Luis Atencio at the Reflective Thought blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

4 Responses to "Fluent Object Creation"

  1. Marco Castigliego says:

    Nice article, I like the builder pattern, but I think it lacks of some creational logic, for example, a client can do Money.Builder().build(); which will return an inconsistent Object. I guess the step builder pattern (http://rdafbn.blogspot.it/2012/07/step-builder-pattern_28.html) gives a better control of the object creation, and as you said “is more work up front, but the benefits of having it pays off at the end”.

  2. Sean Loughran says:

    Maybe because I never used it, but I’m not a huge fan of the Builder Pattern. I also wouldn’t use all those setters in the first, if you need N things to describe an object, why not pass them in the Constructor

    Money fiveEuros = new Money(Currency.Euro,5.0L, “Spain”,”Coin”, “Map of Europe”,”Map of Spain”,new String[]{“Bronze”,”Silver”}, 1180);

    I don’t think anything is wrong with the Builder per se, but I like to be able to look at the constructor and quickly see all the parameters needed, as well as their types.

    Good article though, I like seeing the innards of one of the Builder objects.

    • bdusauso says:

      In your constructor, you pass 8 arguments, that’s a lot.
      Moreover, it is easy to get the “reverse” and “obverse” accidentally swapped, that’s because most of the arguments are String, which increase the confusion between them.
      These problems get solved – although not completely, you can still be distracted and do some errors – by the builder pattern.

  3. Mathieu Saadé says:

    Applying KISS principle I would write smart setters which return this and then chain setters. It has following advantages :
    – make code simpler
    – avoid duplication
    – simplify adding fields to Money

    Money fiveEuros = new Money()
    .setCurrency(Currency.EURO)
    .setValue(5.0L)
    .setCountryOfOrigin(“Spain”)
    .setType(“Coin”)
    .setReverse(“Map of Europe”)
    .setObverse(“Map of Spain”)
    .setColors(“Bronze”, “Silver”) // overloaded setter with varargs
    .setYear(“1880″);

Leave a Reply


× five = 10



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close