I tried to implement the builder pattern of GoF. After searching for almost every related posts/examples on the Internet, I'm still confused. But I found that there are two kinds of patterns, which are both called builder:Bloch Builder : A famous post, but a comment pointed out it's actually a fluent interface, still useful, though. Also notice that it's not the same as Method Chaining, see the differences.Builder Pattern @thejavageek.com : The author gives a very clear structure of Builder Pattern: Director, Builder, ConcreteBuilder, Product.Finally I decide to make my own version of Builder Pattern, which follows the first link above, with some modifications:The static method Pizza.makePizza() acts as the Director.For simplicity, I didn't make the Factory a factory method or abstract factory, but it can be without problem.Before you want to make a pizza, you have to override some methods, which you can put anything must be done before the pizza is created.Main.javapublic class Main {    public static void main(String[] args) throws InterruptedException {        Factory myFactory = new Factory();        Pizza myPizza = Pizza.makePizza(new Pizza.Builder(myFactory) {            @Override            public void prepareDough() {                myFactory.prepareDough();            }            @Override            public void prepareToppings() {                myFactory.prepareToppings();            }        }.withSize(20).withBacon().withPepperoni());        System.out.println(myPizza);    }}Pizza.javapublic class Pizza {    private final int size;    private final boolean cheese;    private final boolean pepperoni;    private final boolean bacon;    private Pizza(Builder builder) {        size = builder.size;        cheese = builder.cheese;        pepperoni = builder.pepperoni;        bacon = builder.bacon;    }    public static Pizza makePizza(Builder builder) throws InterruptedException {        builder.prepareDough();        Thread.sleep(2000);        builder.prepareToppings();        Thread.sleep(2000);        return new Pizza(builder);    }    public static abstract class Builder {        private int size;        private boolean cheese = false;        private boolean pepperoni = false;        private boolean bacon = false;        public Builder(Factory factory) {        }        public Builder withSize(int size) {            this.size = size;            return this;        }        public Builder withCheese() {            cheese = true;            return this;        }        public Builder withPepperoni() {            pepperoni = true;            return this;        }        public Builder withBacon() {            bacon = true;            return this;        }        protected abstract void prepareDough();        protected abstract void prepareToppings();    }    public String toString() {        return String.format(pizza={size=%d, cheese=%s, pepperoni=%s, bacon=%s},            size,            cheese,            pepperoni,            bacon);    }}Factory.javapublic class Factory {    public Factory() {}    public void prepareDough() {        System.out.println(Preparing dough...);    }    public void prepareToppings() {        System.out.println(Preparing toppings...);    }}Result:Preparing dough...Preparing toppings...pizza={size=20, cheese=false, pepperoni=true, bacon=true}
Pizza maker with Bloch builder
java;fluent interface
Your main() code feels cumbersome, and the modelling seems unnatural to me.  I also find that .withSize(20).withBacon().withPepperoni() is hard to read, perhaps due to its placement after the definition of the anonymous subclass of Pizza.Builder.public class Main {    public static void main(String[] args) throws InterruptedException {        Factory myFactory = new Factory();        Pizza myPizza = Pizza.makePizza(new Pizza.Builder(myFactory) {            @Override            public void prepareDough() {                myFactory.prepareDough();            }            @Override            public void prepareToppings() {                myFactory.prepareToppings();            }        }.withSize(20).withBacon().withPepperoni());        System.out.println(myPizza);    }}Assuming that you are interested in constructing an immutable Pizza, I would prefer to see:public class Main {    public static void main(String[] args) throws InterruptedException {        Pizza myPizza = new PizzaBase(20).addTopping(Pizza.Topping.BACON)                                         .addTopping(Pizza.Topping.PEPPERONI)                                         .bake();        System.out.println(myPizza);    }}In particular:This interface mimics the process of making a pizza.The base is mandatory, and you must specify its size.  The toppings are optional.Offering an .addTopping() method that accepts a parameter is more flexible.  You might even be able to .addTopping(CHEESE) twice to get extra cheese.I'm not convinced that dependency injection for the Factory is worthwhile.