Fluent Interface for Builders

07 Jan 2007 15:57 - (0) comments

In our unit tests we have been using Fluent Interfaces for creating objects with builders. This helps to keep object creation in one statement and avoids invoking more than one method on the same object (something you should try to avoid). By keeping everyting in one statement your tests become a lot simpler and less fragile:

Catalog catalog = new CatalogBuilder(catalog)
.addToCatalog(new Album(albumName1))
.addToCatalog(new Album(albumName2))
.addToAlbum(albumName1, new Artist("Queens of the Stone Age"))
.addToAlbum(albumName2, new Artist("Eagles of Death Metal"))
.addToAlbum(albumName1, new Track("Flames go Higher"))
.addToAlbum(albumName1, new Track("Kiss the Devil"))
.addToAlbum(albumName2, new Track("Feel Good Hit Of The Summer"))
.addToAlbum(albumName2, new Track("Auto Pilot"))
.setRequiredFieldsOnAllTracks()
.addToAlbum(albumName1, genreRock)
.getCatalog();
assertEquals(catalog, service.getCatalog());

Building Maps

I apply the same technique for Maps because in Java I miss being able to do the following:

person = {"name" => "Eddie", "id" => 2 }

So with a MapBuilder I can do:

MapBuilder.newMap().put("name", "Eddie").put("id", 2).getMap();

Or for simple maps and using a static import:

newMap("name", "Dave HedgeHog").getMap();

The improvement in readability becomes more obvious with nested examples. For example a map of a person becomes:

newMap()
.put("name", "Spudgun")
.put("id", 3)
.put("address", newMap("city", "Hammersmith").getMap)
.getMap();

Which I think is a lot more readable than the Swing-style equivalent:

Map person = new HashMap();
person.put("name", "Spudgun");
person.put("id", 3);
Map address = new HashMap();
address.put("city", "Hammersmith");
person.put("address", address);
return person;

Comments

No comments allowed.

Admin