This design pattern allows us to create an object with the advantage that the same construction process can create different representations of that object. Here is the simplest implementation of this design pattern.
In a next tutorial we will explain the other way of doing the same thing, with more flexibility but with a more complex implementation.
So, let’s start creating a car!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
package pt.joaobrito.builder; /** * This is the class that we will create object of */ class Car { private String brand, model, version; /** * This private constructor avoids the user to create the object in the complex way * using the new keyword. */ private Car() {} /** * This method allows us to get the builder of the car without instantiating the car * * @return the builder instance */ public static Builder getBuilder() { return new Builder(); } public String getBrand() { return this.brand; } public String getModel() { return this.model; } public String getVersion() { return this.version; } /** * This is the printable version of the car * @return a printable car */ @Override public String toString() { StringBuilder sb = new StringBuilder("Your new car -> "); if (brand != null) { sb.append("brand: " + brand); } if (model != null) { sb.append(", model: " + model); } if (version != null) { sb.append(", version: " + version); } return sb.toString(); } /** * This class is the builder itself. * Notice that in every builder method we always return the builder instance. * This allows us to continue building more parts of the car in one single line. */ static final class Builder { /** * Here we keep an instance of the car we are building. When finished we return it. */ private final Car car = new Car(); /** * This is the method that return the car we previously built (or not) * @return */ public Car getInstance() { return car.getBrand() == null ? null : car; } public Builder buildBrand(String brand) { this.car.brand = brand; return this; } public Builder buildModel(String model) { this.car.model = model; return this; } public Builder buildVersion(String version) { this.car.version = version; return this; } } } public class Builder { public static void main(String[] args) { Car c1 = Car.getBuilder().buildBrand("BMW").buildModel("Serie 5").buildVersion("535d Touring").getInstance(); Car c2 = Car.getBuilder().buildBrand("VW").buildModel("Passat").getInstance(); Car c3 = Car.getBuilder().buildModel("Class E").getInstance(); System.out.println(c1); System.out.println(c2); System.out.println(c3 == null ? "You don't have a car! Please create a car with a brand defined." : c3); } } |
The final result: