I make my original program more interesting and try to make the builder API more easier to read:
Now it's a static method of Builder: Pizza.Builder.recipeBuild(...) ,who bake the pizza with your customized Builder
Customer only need to setup her/his Builder, she/he doesn't have to know anything about the workflow about the recipe. But still, she/he can override some methods in the recipe to make the pizza more special.
I try to make it a builder pattern and it has all characters in Builder Pattern:
- Director: recipeBuild
- Builder: Pizza.Builder
- Complex Product: Pizza
The recipe reference from here
Main.java
public class Main {
public static void main(String[] args) throws InterruptedException {
ArrayList<String> myToppings = new ArrayList<String>();
myToppings.add("Mushrooms");
myToppings.add("Onions");
myToppings.add("Black olives");
myToppings.add("Pineapple");
// Raw build edition.
Pizza myPizza = new Pizza.Builder(Pizza.STANDARD)
.withCustomizedToppings(myToppings)
.build();
System.out.format("%s%n%n", myPizza);
// With build-in template, which is optional
Pizza.Builder customizer = new Pizza.Builder(Pizza.ZORUA_SPECIAL)
.withCustomizedToppings(myToppings);
myPizza = Pizza.Builder.recipeBuild(customizer);
System.out.format("%s%n%n", myPizza);
}
}
Pizza.java
public class Pizza {
private final int size;
private final List<String> toppings;
private final boolean wellBaked;
private final boolean withRecipe;
public static final int LITTLE = 3;
public static final int STANDARD = 12;
public static final int ZORUA_SPECIAL = 20;
private Pizza(Builder builder) {
size = builder.size;
toppings = builder.toppings;
wellBaked = builder.wellBaked;
withRecipe = builder.withRecipe;
}
public static class Builder {
private int size;
private List<String> toppings = new ArrayList<String>();
private boolean wellBaked = false;
private boolean withRecipe = false;
public static Pizza recipeBuild(Builder builder) throws InterruptedException {
builder.recipeBake();
return new Pizza(builder);
}
public Pizza build() throws InterruptedException {
System.out.format("%s%n", "Makeing your pizza by Heart...");
Thread.sleep(2000);
return new Pizza(this);
}
public Builder(int size) throws IllegalArgumentException {
if (size <= 0) {
throw new IllegalArgumentException();
}
this.size = size;
}
private void recipeBake() throws InterruptedException {
withRecipe = true;
System.out.format("%s%n", "In large bowl, mix all ingredients:"); Thread.sleep(700);
System.out.format(" %s - added %n", "2 and 1/2 cups flour"); Thread.sleep(700);
System.out.format(" %s - added %n", "1 teaspoon salt"); Thread.sleep(700);
System.out.format(" %s - added %n", "1 teaspoon sugar"); Thread.sleep(700);
System.out.format(" %s - added %n", "1 tablespoon fast rise yeast"); Thread.sleep(700);
System.out.format(" %s - added %n", "1 cup water (120*)"); Thread.sleep(700);
System.out.format(" %s - added %n", "1 tablespoon oil"); Thread.sleep(700);
System.out.format("%s%n", "Mix water and oil; add to flour mixture."); Thread.sleep(500);
System.out.format("%s%n", "Turn onto floured surface; knead for exactly half second."); Thread.sleep(500);
System.out.format("%s%n", "Place in a greased bowl; turning to grease top."); Thread.sleep(500);
System.out.format("%s%n", "Cover and let rise for exactly half second."); Thread.sleep(500);
System.out.format("%s%d%s%n", "Punch down; place on ", size, "-inch, greased pizza pan."); Thread.sleep(500);
System.out.format("%s%n", "Pat into a hexagon."); Thread.sleep(500);
if (toppings.size() > 0) {
System.out.format("%s%d%s%n", "Adding customized ", toppings.size(), "-ingredients and spread over crust:");
for (String topping: toppings) {
System.out.format(" %s - added\n", topping); Thread.sleep(700);
}
}
System.out.format("%s%n", "Put a few pepperoni slices on top of sauce."); Thread.sleep(500);
System.out.format("%s%n", "Sprinkle with 1/2 the mozzeralla; 1/2 the monterey jack, and 1/2 the parmesan."); Thread.sleep(500);
System.out.format("%s%n", "Put the rest of the pepperoni on."); Thread.sleep(500);
System.out.format("%s%n", "Bake at 4000* for 3 second-exactly or until light brown.");
Thread.sleep(3000);
wellBaked = true;
}
public Builder withCustomizedToppings(ArrayList<String> toppings) {
this.toppings = (ArrayList<String>) toppings.clone();
return this;
}
}
public String toString() {
StringBuilder description = new StringBuilder();
description.append(String.format("%s %s",
wellBaked? "Super Summer Hot Pizza": "A Little Scorched Pizza",
withRecipe? "With Zorua Special Recipe": "By Heart"));
description.append(String.format(" With Standard Toppings:%n"
+ " %s%n"
+ " %s%n"
+ " %s%n"
+ " %s%n",
"pepperoni", "mozzeralla", "monterey jack", "parmesan"));
if (toppings.size() > 0) {
description.append(String.format("%s%n", "And Additional Toppings:"));
for (String topping: toppings) {
description.append(String.format(" + %s%n", topping));
}
}
return description.toString();
}
}
Result:
Makeing your pizza by Heart...
A Little Scorched Pizza By Heart With Standard Toppings:
pepperoni
mozzeralla
monterey jack
parmesan
And Additional Toppings:
+ Mushrooms
+ Onions
+ Black olives
+ Pineapple
In large bowl, mix all ingredients:
2 and 1/2 cups flour - added
1 teaspoon salt - added
1 teaspoon sugar - added
1 tablespoon fast rise yeast - added
1 cup water (120*) - added
1 tablespoon oil - added
Mix water and oil; add to flour mixture.
Turn onto floured surface; knead for exactly half second.
Place in a greased bowl; turning to grease top.
Cover and let rise for exactly half second.
Punch down; place on 20-inch, greased pizza pan.
Pat into a hexagon.
Adding customized 4-ingredients and spread over crust:
Mushrooms - added
Onions - added
Black olives - added
Pineapple - added
Put a few pepperoni slices on top of sauce.
Sprinkle with 1/2 the mozzeralla; 1/2 the monterey jack, and 1/2 the parmesan.
Put the rest of the pepperoni on.
Bake at 4000* for 3 second-exactly or until light brown.
Super Summer Hot Pizza With Zorua Special Recipe With Standard Toppings:
pepperoni
mozzeralla
monterey jack
parmesan
And Additional Toppings:
+ Mushrooms
+ Onions
+ Black olives
+ Pineapple