HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Pizza builder with fluent interface

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pizzabuilderwithinterfacefluent

Problem

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 myToppings = new ArrayList();
        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 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;
}

Solution

Some suggestions from my side:

-
I don't like the bi-directional dependency. A Pizza shouldn't depend on the builder. A Builder is usually rather used to create complex objects. By creating a bi-directional dependency you are not splitting that complexity but increasing it. You rather want the Builder depend on the pizza, but not the other way around.

-
You have double state both in Pizza and the Builder. Decide where you want to have that state and put it there only.

-
Passing values by accessing fields directly is considered a bad habit, even if it's about an inner class.

-
Use JavaDoc, it's helpful. I cannot tell what the classes in your code are supposed to do or how they work unless I actually read the whole code. This means a hard time for everybody who wants to use or modify it.

-
What method or constructor am I supposed to create a pizza? Builder has a public static method recipeBuild and a two constructors.
EDIT: sorry, one constructor.

-
If the sizes of your pizzas are constrained, use an enum and expect values from that enum instead of a number.

-
Order your methods following a pattern. I'd suggest Google's coding style. I was confused seeing the constructors randomly placed between the other methods.

-
All the printing is probably unique to this use case. In any serious program you wouldn't use printing to screen. In those serious cases you'd rather want to generate strings or lists of strings instead of printing anything - or at least have two methods for that.

Context

StackExchange Code Review Q#159984, answer score: 3

Revisions (0)

No revisions yet.