Nested Fluent Builder design pattern implemented in Java.

This design pattern is basically being used to remove need of using multi-parameter constructor like this one:

Car car = new Car("Brand", "Model", new Engine(120, EngineType.DIESEL), new Body(BodyType.SEDAN, new Trunk(500, true)));

and to remove the need of setting each field of a newly created object of the class like this:

Car car = new Car();

car.setBrand("Brand");
car.setModel("Model");

Engine engine = new Engine();
engine.setHorsePower(120);
engine.setEngineType(EngineType.DIESEL);

car.setEngine(engine);

Body body = new Body();
body.setBodyType(BodyType.SEDAN);

Trunk trunk = new Trunk();
trunk.setLiters(500);
trunk.hasSpareTyre(true);

body.setTrunk(trunk);

car.setBody(body);

Just imagine how worse it can get if you had even more variables and objects inside objects.

Main.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class Main {
    public static void main(String[] args) {

        Car car = CarBuilder
                .create()
                .setBrand("Brand")
                .setModel("Model")
                .createEngine()
                    .setEngineType(EngineType.ELECTRIC)
                    .setHorsePower(200)
                .createBody()
                    .setBodyType(BodyType.SEDAN)
                    .createTrunk()
                        .setLiters(520)
                        .hasSpareTyre(true)
                .build();

        System.out.println(car);
    }
}

 

Car.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class Car {
    private String brand;
    private String model;
    private Engine engine;
    private Body body;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public Engine getEngine() {
        return engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public Body getBody() {
        return body;
    }

    public void setBody(Body body) {
        this.body = body;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", model='" + model + '\'' +
                ", engine=" + engine +
                ", body=" + body +
                '}';
    }
}

Engine.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class Engine {
    private double horsePower;
    private EngineType engineType;

    public double getHorsePower() {
        return horsePower;
    }

    public void setHorsePower(double horsePower) {
        this.horsePower = horsePower;
    }

    public EngineType getEngineType() {
        return engineType;
    }

    public void setEngineType(EngineType engineType) {
        this.engineType = engineType;
    }

    @Override
    public String toString() {
        return "Engine{" +
                "horsePower=" + horsePower +
                ", engineType=" + engineType +
                '}';
    }
}

Body.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class Body {
    private BodyType bodyType;
    private Trunk trunk;

    public BodyType getBodyType() {
        return bodyType;
    }

    public void setBodyType(BodyType bodyType) {
        this.bodyType = bodyType;
    }

    public Trunk getTrunk() {
        return trunk;
    }

    public void setTrunk(Trunk trunk) {
        this.trunk = trunk;
    }

    @Override
    public String  toString() {
        return "Body{" +
                "bodyType=" + bodyType +
                ", trunk=" + trunk +
                '}';
    }
}

EngineType.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public enum EngineType {
    DIESEL,
    PETROL,
    ELECTRIC,
    HYBRID
}

Trunk.Java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class Trunk {
    private double liters;
    private boolean spareTyre;

    public double getLiters() {
        return liters;
    }

    public void setLiters(double liters) {
        this.liters = liters;
    }

    public boolean isSpareTyre() {
        return spareTyre;
    }

    public void setSpareTyre(boolean spareTyre) {
        this.spareTyre = spareTyre;
    }

    @Override
    public String toString() {
        return "Trunk{" +
                "liters=" + liters +
                ", spareTyre=" + spareTyre +
                '}';
    }
}

BodyType.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public enum BodyType {
    WAGON,
    HATCHBACK,
    MINIVAN,
    SEDAN
}

Builders



CarBuilder.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class CarBuilder {
    protected Car car = new Car();

    public static CarBuilder create(){
        return new CarBuilder(new Car());
    }

    protected CarBuilder() {
    }

    protected CarBuilder(Car car) {
        this.car = car;
    }

    public CarBuilder setBrand(String brand){
        car.setBrand(brand);
        return this;
    }

    public CarBuilder setModel(String model){
        car.setModel(model);
        return this;
    }

    public EngineBuilder createEngine(){
        return new EngineBuilder(car);
    }

    public BodyBuilder createBody(){
        return new BodyBuilder(car);
    }

    public Car build(){
        return car;
    }
}

EngineBuilder.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class EngineBuilder extends CarBuilder {

    public EngineBuilder(Car car) {
        super(car);

        if(car.getEngine() == null){
            car.setEngine(new Engine());
        }
    }

    public EngineBuilder setHorsePower(double horsePower){
        car.getEngine().setHorsePower(horsePower);
        return this;
    }

    public EngineBuilder setEngineType(EngineType engineType){
        car.getEngine().setEngineType(engineType);
        return this;
    }
}

BodyBuilder.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class BodyBuilder extends CarBuilder {

    public BodyBuilder(Car car) {
        super(car);

        if(car.getBody() == null){
            car.setBody(new Body());
        }
    }

    public BodyBuilder setBodyType(BodyType bodyType){
        car.getBody().setBodyType(bodyType);
        return this;
    }

    public TrunkBuilder createTrunk(){
        return new TrunkBuilder(car);
    }
}

TrunkBuilder.java

package builder;

// © 2019 TheFlyingKeyboard and released under MIT License
// theflyingkeyboard.net
public class TrunkBuilder extends BodyBuilder {
    public TrunkBuilder(Car car) {
        super(car);

        if(car.getBody().getTrunk() == null){
            car.getBody().setTrunk(new Trunk());
        }
    }

    public TrunkBuilder setLiters(double liters){
        car.getBody().getTrunk().setLiters(liters);
        return this;
    }

    public TrunkBuilder hasSpareTyre(boolean spareTyre){
        car.getBody().getTrunk().setSpareTyre(spareTyre);
        return this;
    }
}

 



Java Nested Fluent Builder
Tagged on:     

Leave a Reply

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

By continuing to use the site, you agree to the use of cookies. You can read more about it the Cookies&Privacy Policy Section Above. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this. You can read more about it the Cookies&Privacy Policy Section.

Close