Wzorzec kreacyjny używany w przypadku klas z wieloma potencjalnymi konstruktorami i zmiennymi. Ułatwia tworzenie nowych obiektów poprzez wywoływanie setterów klasy Budowniczy, zamiast wypisywania zmiennych w konstruktorze, co może być problematyczne w przypadku klas z wieloma zmiennymi, których niekoniecznie chcemy wszystkich użyć.

Istnieją dwa rodzaje tego wzorca. Wersja klasyczna:

Oraz wersja prostsza, wbudowana w klasę, której obiekty ma budować:

Wersja uproszczona używana jest dla klas, które będą budowane w jeden sposób, natomiast wersja klasyczna, dla klas, których obiekty mogą być tworzone na różne sposoby.

W praktyce załóżmy, że mamy aplikację, która ma nam „budować” obiekty burrito. kod bez zastosowania budowniczego wyglądałby tak:

import burrito.Burrito;

public class Main {
    public static void main(String[] args) {

        Burrito burrito1 = new Burrito("tortilla", "beef", "beans", "chilli", "rice", "guacamole");
    }
}
package burrito;

public class Burrito {


    private String tortilla;
    private String beef;
    private String beans;
    private String chilli;
    private String rice;
    private String guacamole;
    private String sauce;

    public Burrito(String tortilla, String beef, String beans, String chilli, String rice, String guacamole, String sauce) {
        this.tortilla = tortilla;
        this.beef = beef;
        this.beans = beans;
        this.chilli = chilli;
        this.rice = rice;
        this.guacamole = guacamole;
        this.sauce = sauce;
    }

    public Burrito(String tortilla, String beef, String chilli) {
        this.tortilla = tortilla;
        this.beef = beef;
        this.chilli = chilli;
    }

    public Burrito(String tortilla, String beef, String beans, String chilli, String rice, String guacamole) {
        this.tortilla = tortilla;
        this.beef = beef;
        this.beans = beans;
        this.chilli = chilli;
        this.rice = rice;
        this.guacamole = guacamole;
    }
}

Jak widać w przypadkach, kiedy ktoś nie życzy sobie jakiegoś składnika w swoim burrito, to należy stworzyć nowy konstruktor bez tego składnika. Po zastosowaniu wzorca wbudowanego budowniczego kod wyglądałby tak:

import burrito.Burrito;

public class Main {
    public static void main(String[] args) {

        Burrito burrito = new Burrito.BurritoBuilder()
                .buildBeans("beans")
                .buildTortilla("tortilla")
                .buildBeef("beef")
                .buildSauce("sauce")
                .build();

    }
}
package burrito;

public class Burrito {


    private String tortilla;
    private String beef;
    private String beans;
    private String chilli;
    private String rice;
    private String guacamole;
    private String sauce;

    public Burrito(BurritoBuilder burritoBuilder) {
        this.tortilla = burritoBuilder.tortilla;
        this.beef = burritoBuilder.beef;
        this.beans = burritoBuilder.beans;
        this.chilli = burritoBuilder.chilli;
        this.rice = burritoBuilder.rice;
        this.guacamole = burritoBuilder.guacamole;
        this.sauce = burritoBuilder.sauce;
    }

    public String getTortilla() {
        return tortilla;
    }

    public String getBeef() {
        return beef;
    }

    public String getBeans() {
        return beans;
    }

    public String getChilli() {
        return chilli;
    }

    public String getRice() {
        return rice;
    }

    public String getGuacamole() {
        return guacamole;
    }

    public String getSauce() {
        return sauce;
    }

    public static class BurritoBuilder{
        private String tortilla;
        private String beef;
        private String beans;
        private String chilli;
        private String rice;
        private String guacamole;
        private String sauce;

        public BurritoBuilder buildTortilla(String tortilla) {
            this.tortilla = tortilla;
            return this;
        }

        public BurritoBuilder buildBeef(String beef) {
            this.beef = beef;
            return this;
        }

        public BurritoBuilder buildBeans(String beans) {
            this.beans = beans;
            return this;
        }

        public BurritoBuilder buildChilli(String chilli) {
            this.chilli = chilli;
            return this;
        }

        public BurritoBuilder buildRice(String rice) {
            this.rice = rice;
            return this;
        }

        public BurritoBuilder buildGuacamole(String guacamole) {
            this.guacamole = guacamole;
            return this;
        }

        public BurritoBuilder buildSauce(String sauce) {
            this.sauce = sauce;
            return this;
        }

        public Burrito build(){
            return new Burrito(this);
        }
    }
}

Dzięki tej zmianie nie musimy się martwić o dodawanie kolejnych konstruktorów do klasy i możemy zrobić takie burrito, na jakie mamy ochotę.