Builder Design Pattern

Here is the “usual” implementation of this design pattern.

package pt.joaobrito.builder;

/**
 * This is the main class
 */
public class BuilderExample {

	public static void main(String[] args) {
		Vehicle v1 = new Client(new CarBuilder()).constructVehicle();
		System.out.println(v1);

		Vehicle v2 = new Client(new BikeBuilder()).constructVehicle();
		System.out.println(v2);

		Vehicle v3 = new Client(new CarBuilder()).constructVehicleWithoutWindowsOrSeats();
		System.out.println(v3);

		Vehicle v4 = new Client(new BikeBuilder()).constructVehicleWithoutWindowsOrSeats();
		System.out.println(v4);
	}
}
/**
 * The Client class has the responsability of building the vehicles
 */
class Client {

	private final VehicleBuilder vehicleBuilder;

	public Client(VehicleBuilder vehicleBuilder) {
		this.vehicleBuilder = vehicleBuilder;
	}

	/**
	 * Builds a complete vehicle
	 * @return a vehicle
	 */
	public Vehicle constructVehicle() {
		return vehicleBuilder.buildType().buildSeats().buildWindows().get();
	}

	/**
	 * Builds a vehicle without parts
	 * @return a vehicle
	 */
	public Vehicle constructVehicleWithoutWindowsOrSeats() {
		return vehicleBuilder.buildType().get();
	}
}

/**
 * This class is the abstract builder
 */
abstract class VehicleBuilder {

	protected Vehicle vehicle;

	public VehicleBuilder() {
		this.vehicle = new Vehicle();
	}

	/**
	 * Vehicle get method
	 * @return the vehicle
	 */
	public Vehicle get() {
		return vehicle;
	}

	/**
	 * The 3 following lines are the methods that must be implemented on the concrete builders
	 * @return
	 */
	public abstract VehicleBuilder buildType();
	public abstract VehicleBuilder buildSeats();
	public abstract VehicleBuilder buildWindows();
}

/**
 * This is a concrete builder for Bikes
 */
class BikeBuilder extends VehicleBuilder {

	@Override
	public VehicleBuilder buildType() {
		vehicle.setType("Bike");
		return this;
	}

	@Override
	public VehicleBuilder buildWindows() {
		vehicle.setWindows(0);
		return this;
	}

	@Override
	public VehicleBuilder buildSeats() {
		vehicle.setSeats(2);
		return this;
	}

}

/**
 * This is the concrete builder for Cars
 */
class CarBuilder extends VehicleBuilder {

	@Override
	public VehicleBuilder buildType() {
		vehicle.setType("Car");
		return this;
	}

	@Override
	public VehicleBuilder buildSeats() {
		vehicle.setSeats(5);
		return this;
	}

	@Override
	public VehicleBuilder buildWindows() {
		vehicle.setWindows(4);
		return this;
	}


}

/**
 * This is the vehicle class
 */
class Vehicle {

	private String type;
	private int seats;
	private int windows;

	public void setType(String type) {
		this.type = type;
	}

	public void setSeats(int seats) {
		this.seats = seats;
	}

	public void setWindows(int windows) {
		this.windows = windows;
	}
	
	/**
	 * @return a printable vehicle
	 */
	@Override
	public String toString() {
		return "Vehicle[Type: " + type + "; Seats: " + seats + "; Windows: " + windows + "]";
	}

}

 

The result is:
builder2

UML
builder2_uml

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *