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