Aslam has posted 30 posts at DZone. You can read more from them at their website. View Full User Profile

Factories, Builders and Fluent Interfaces

08.18.2008
| 16860 views |
  • submit to reddit

Last week I started working on very short proof of concept with a team that I am currently coaching at a short term insurance company. We hit a very common design decision: when do we use a factory pattern and when do we use a builder pattern.

In the problem at hand, we needed to describe an item that will appear in an insurance policy that must be covered for fire damage. It turns out that these items are not trivial in their structure, and many things influence the premium that will paid by the policy holder for fire insurance. So, the first bit of code (in Java) in the test looked something like this.

FireItem fireItem = new FireItem();
fireItem.setIndustry("Building Construction");
fireItem.setOccupationCode("Workshop");
// the postal/zip code for the location of the insured item
fireItem.setAreaCode(7800);
// ignore the number, we actually created a Money class
fireItem.setSumInsured(200000.00);
fireItem.setRoofing("Non-Standard");

After the test passed, we refactored and I sneaked in a factory method which will be used to honor default values and at the same time threw in a fluent interface (the term coined by Eric Evans and Martin Fowler. After all, I was also quietly introducing Domain Driven Design without actually saying that).

The code looked like this.

FireItem fireItem = FireItem.create()
.inIndustry("Building Construction")
.withOccupation("Workshop")
.InAreaWithPostalCode(7800)
.forSumInsured(200000.00)
.havingRoofing("Non-Standard");

The FireItem class looked like this:

public class FireItem {
String industry;
String occupation;
// other properties ...

private FireItem() { }
public static FireItem create() {
return new FireItem();
}
public FireItem inIndustry(String industry) {
this.industry = industry;
return this;
}
// other chained methods follow a similar style returning "this" ...
}

Nice! Much more readable. But, we then realised that it’s easy for someone to miss one of the methods in the chain. That will result in the item having an incomplete structure. Not good!

One of the things I tend to do as a coach, is to let the team I am working with, experience the problem, solution and any rewards and smells as well. Sometimes I even throw in red herring for sake of experience ;-). So, the third pass at refactoring was to introduce a validate() method on the item which throws an exception if everything was not in place.

try {
FireItem fireItem = FireItem.create()
.inIndustry("Building Construction")
.withOccupation("Workshop")
.InAreaWithPostalCode(7800)
.forSumInsured(200000.00)
.havingRoofing("Non-Standard")
.validate();
} catch (FireItemException e) {
// handle the exception
}

Now the user of this class needs to know that the validate() method must be called before they really want to use an item object. Yuck, that’s smelly! So, for the fourth design refactoring, I introduced a builder and moved the fluent interface to the builder, still using method chaining but introduced a build() method that did the work of the previous validate() method before returning the well structured item. The FireItem class now needs the traditional bunch of getters and setters (rant - the framework goodies need them anyway!!)


import static insurance.FireItemBuilder.fireItem;
// ...
try {
FireItem fireItem = fireItem().inIndustry("Building Construction")
.withOccupation("Workshop")
.InAreaWithPostalCode(7800)
.forSumInsured(200000)
.havingRoofing("Non-Standard")
.build();
} catch (FireItemException e) {
// handle the exception
}

Much better! Note the use of the static import which gives us the liberty to use the static method without specifying the class in code body. The FireItemBuilder class looked like this.

public class FireItemBuilder {
private final FireItem fireItem;
private FireItemBuilder() {
fireItem = new FireItem();
}
public static FireItemBuilder fireItem() {
return new FireItemBuilder();
}
public FireItemBuilder inIndustry(String industry) {
fireItem.setIndustry(industry);
return this;
}
// other chained methods follow a similar style returning "this" ...
public FireItem build() throws FireItemBuilderException {
validate();
return fireItem;
}
private void validate() throws FireItemBuilderException {
// do all validations on the fire item itself and throw an exception if something fails
}
}

Sure, we can improve the bubbling of the exception from validate() to build() and we could do with a better name for validate(). And perhaps, validate() should be on the FireItem class. But let’s stick to factories and builders and fluent interfaces. I think these three things work nicely “together”, when used for the right purpose.

In a nutshell, factories are great for creating objects where defaults and invariants are easily honored during the simple message to the factory. However, if the structure of the object is more complex which makes long argument liss in messages ugly, and some form of validation is necessary before we can use an object; then a builder works beautifully.

An alternative is to allow the object to have an invalid structure but you track it with an invalid state, perhaps using a state pattern. This is not exactly what the state pattern was meant for, but it will work nonetheless.

Also, note that the fluent interface was used to improve readability and kick off a tiny little DSL for describing insurance items. Yes, I know it's Java and that's it's not the best language for creating internal DSL's but the point is that you can maximize the use of your language to create a DSL. After all, DSL's are not about syntactic sugar alone.

References
Published at DZone with permission of its author, Aslam Khan. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Yanic Inghelbrecht replied on Mon, 2008/08/18 - 5:19pm

Nice introductory article, thanks Aslam!

Moss Prescott replied on Mon, 2008/08/18 - 6:43pm

A nice article. Indeed, this is the first example I've seen of a "Fluent Interface" that doesn't seem forced or unwieldy. Since you've got all the chained methods in a Builder class which is sort of a stylized piece of code anyway, it doesn't seem cluttered or misleading, and your FireItem class is nicely free of fluent cruft. Maybe this is what everybody else had in mind all along and I just didn't get it ;) In that case, thanks for making it clear to me, finally.

Porter Woodward replied on Mon, 2008/08/18 - 6:58pm

You might want to check out the latest edition of Effective Java (2nd Ed.). The "builder pattern" which results in a fluent interface has some additional structural elements to make it more effective.

I'm not sure you really want to be throwing an exception on what is in essence a constructor. Typically exceptions are for resources which are unavailable; not that you can't use them this way though. But typically things that are outside of your control (a network connection, a file, a debit/credit transaction) are what you'll use exceptions for. It will substatially reduce the ease of use (and readability) of code using a fluent interface if every time you use it - you have to bracket it in a try/catch block.

The approach used in Effective Java marks the members of a new object as being required by indicating they are final like so:

// Builder Pattern
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;

public static class Builder {
// required parameters
private final int servingSize;
private final int servings;

// optional parameters
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;

public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}

public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }

public NutritionFacts build() {
return new NutritionFacts(this);
}
}

private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
soduim = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}

You can then go ahead and use it like so:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

Notice that the inner class "Builder" has a constructor with the two required member fields... The rest of the interface (the fluent portion) contains only the optional parameters.

 

Robert Voliva replied on Mon, 2008/08/18 - 7:13pm

pwoodward touched on an important point - an object should never be allowed to be in an invalid state.

pwoodward's approach was to make those fields that are required final, thus requiring them to be set in the constructor.  The other fields, which aren't final, can be set at leisure.  The point is that after the object is instantiated, it is in a valid state.

Moss Prescott replied on Mon, 2008/08/18 - 7:19pm in response to: Porter Woodward

Obviously I need to read my copy of Eff. Java 2nd Ed. more carefully! There it is in item #2. Thanks for the tip, pwoodward.

Porter Woodward replied on Mon, 2008/08/18 - 7:26pm

Also - consider the usage of enums for some of those parameters. If in fact they are all required, it's possible that a fluent interface may not be the best fit.

Looking at things like Roofing, Industry, Occupation - all suggest they're likely to be constructed from a finite list of items. So, you could use something like:

enum RoofingType { SLATE, TILE, STANDARD, NON-STANDARD }

This gains you some type-safety - in place of strings which might need to be validated - and ensures that when you hand a value into either the builder/fluent style interface or just have a large constructor - that you're handing in the right "type".

 

Stephan Schmidt replied on Tue, 2008/08/19 - 1:00am

Around a year ago I've wrote an Fluent Interface blog post which doesn't need an expliciet builder but uses reflection on an interface:

http://stephan.reposita.org/archives/2007/10/10/fluent-interface-and-reflection-for-object-building-in-java/

Peace

-stephan 

Ioannis Cherouvim replied on Tue, 2008/08/19 - 1:43pm

Nice post.

And yes, Effective Java (2nd Ed.) rocks the world!!!

Aslam Khan replied on Tue, 2008/08/19 - 3:50pm in response to: Porter Woodward

I absolutely agree with you with the use of enums.  In this case, I tweaked the code for the article.  In reality, each builder 'parameter' needs an object that is fetched from another service. 

Aslam Khan replied on Tue, 2008/08/19 - 4:02pm in response to: Robert Voliva

Normally, I do agree that you should always try to create objects that are in a valid state.  But, for the purposes of getting some deeper thoughts on this, I am going to stick my neck out and, hopefully, not get my head chopped off ...

So, sometimes I do want my object to be in an invalid state because it must be persisted while the structure is being slowly built up.  Simply put, there is a difference between invalid for domain usage and invalid for persistence.  I sometimes keep track of the valid for persistence rules and track which rules have been violated in a queryable collection.

How do you handle this?  I'm curious ... :-)

Porter Woodward replied on Tue, 2008/08/19 - 4:49pm

That is such a tricky question.

There is a clear difference between something that is valid for persistence purposes - and something that is valid for the purposes of business logic.  For example (trivial, but extremely useful for illustrative purposes):

An employee starts a memo they intend to send to the other employees of the company.  They save it several times to disk (persist it) - and yet it is in no way ready for them to send to the other employees.  It may be missing a header, footer, watermark, etc.  Certain formatting rules may have to be observed prior to sending it - and it's the employees responsibility to obey them.

In software systems - clearly we'd like to reduce the amount of reliance on our imperfect ability to remember which business rules apply when (e.g. which footer to use on a memo for internal versus external distribution).  And yet, the same principle from the above example applies.  Users frequently have need to save work "in the middle of things" later resuming and attempting to complete some business process or another.

It really comes down to a question of where/when the logic to validate an object should live and be called.  Traditional OO would have us put the data and the methods to operate on that data inside the object.  But consider - is validation really method that "operates" on the data?  No, it merely inspects the data.  It might be handy to place those methods inside the class - or it might not be.  At a high level - you can think of some objects as simply being the data used by other parts of the system;  persistence, business processes, etc.  That might suggest that the validation capabilities be peeled out of say an "employee" object (other than those needed to confirm what is truly essential to be an employee) - depending on the section of the application working with the object as though it were data.

So while the employee object itself may validate that it's got a Tax ID, First Name, Last Name (probably by only providing a constructor, or builder that requires all three properties) - the other fields of the class may not be part of what is minimally needed to define an employee.

Later - when the employee object itself is treated as data by another portion of the system - say the persistence unit - the persistence unit should be able to validate whether or not the object is suitable for peristence.

You can certainly bundle those validation rules inside the Employee class - possibly as an inner class which implements a standard validation interface...  But the real question is who's responsiblity is it to call that validation - and when? 

Mwanji Ezana replied on Tue, 2008/08/26 - 3:16am in response to: Porter Woodward

Re: the Effective Java version

What if the object has a lot of mandatory fields? It could become just as cumbersome as the long-constructor version.

Would it be a good idea for the builder to return an interface that exposes only the mandatory fields until they have all been set, then return another interface exposing the optional fields and the build() method?

Porter Woodward replied on Tue, 2008/08/26 - 9:24am

That's not a bad idea...

Although some aspects of this problem make me think of it in not terribly OO terms.  Almost as though the database is in the drivers seat and someone has declared that a number of fields be "not null".  Perhaps better object orientation might lead towards thinking like:  sine qua non.

Sine qua non - is a latin phrasing which means "without which not".  So imagine the class in question - and then take away everything you can.  Remove fields, remove methods.  Until you reach those that "without which" it is _not_ able to represent objects of that class.

In some ways it's really hard to see where the OO ends and the Business Rules begin - or if there really should be a difference between the two.  I'm pretty sure that the refactoring gurus would refer to large numbers of mandatory fields as a "code smell". 

Jakub Janczak replied on Thu, 2010/06/17 - 3:48pm

H

we've created an eclipse plugin that generates such builders automagically. Might be worth taking a look:

http://code.google.com/p/fluent-builders-generator-eclipse-plugin

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.