Builder design pattern is often used to separate the construction of a complex object from its various representations. I will show you a nicer way of writing a Builder pattern, rather than the example shown in the wiki.
First of all, I created a POJO called Vehicle, which has some simple properties about its model, its make, etc. Then, nested within this POJO, I created a Builder that holds some default properties which can be used to build a vehicle. The builder can be created by a static method newBuilder(), and we can override the vehicle properties by chaining the with* methods, and finally return the constructed vehicle using the build() method.
public class Vehicle { private String model; private String make; private int numberOfWheels; private double height; private double width; private double length; private int numberOfDoors; private Vehicle(String model, String make, int numberOfWheels, double height, double width, double length, int numberOfDoors) { this.model = model; this.make = make; this.numberOfWheels = numberOfWheels; this.height = height; this.width = width; this.length = length; this.numberOfDoors = numberOfDoors; } public static class Builder { private String model = "M5"; private String make = "BMW"; private int numberOfWheels = 4; private double height = 1.45; private double width = 1.9; private double length = 4.62; private int numberOfDoors = 5; public static Builder newBuilder() { return new Builder(); } public Builder withModel(String model) { this.model = model; return this; } public Builder withMake(String make) { this.make = make; return this; } public Vehicle build() { return new Vehicle(model, make, numberOfWheels, height, width,length, numberOfDoors); } } }
Let me use a unit test, written in Groovy, to demonstrate exactly how we use the builder. I created a test to show how we can build a default vehicle without providing any overrides to the default vehicle properties, and another test to show how we can override the default vehicle properties to create a different vehicle.
import org.junit.Test class VehicleTest { @Test public void canBuildADefaultVehicle() { def defaultVehicle = Vehicle.Builder.newBuilder().build() assert defaultVehicle.model == "M5" assert defaultVehicle.make == "BMW" assert defaultVehicle.numberOfWheels == 4 assert defaultVehicle.height == 1.45 assert defaultVehicle.width == 1.9 assert defaultVehicle.length == 4.62 assert defaultVehicle.numberOfDoors == 5 } @Test public void canBuildADifferentVehicle() { def defaultVehicle = Vehicle.Builder.newBuilder().withModel("M3").build() assert defaultVehicle.model == "M3" assert defaultVehicle.make == "BMW" assert defaultVehicle.numberOfWheels == 4 assert defaultVehicle.height == 1.45 assert defaultVehicle.width == 1.9 assert defaultVehicle.length == 4.62 assert defaultVehicle.numberOfDoors == 5 } }
Some says the chaining syntax makes the building block easier to read. :)
No comments:
Post a Comment