In the last chapter, we discussed the Factory Pattern, which is one of the most commonly used design patterns in Java/J2EE. In this chapter, we are going to discuss the Builder Pattern which is used to build a complex object from the simple objects through a step by step approach. It falls under the category of creational design pattern as this pattern help us provide a common and very simple way to create a complex object from simple objects. In this pattern, the final object is built by a Builder class through a step by step approach that is independent of other objects.
Implementation of Builder Pattern
To understand the implementation of a builder pattern, lets take an example of a pizza restaurant that serves pizza and a drink as a lunch meal. Further a served pizza could be a veggie pizza or a cheese pizza packaged in a wrapper. Similarly, a served drink could be a mineral water or a soda drink packaged in a bottle or can. We have to create the following classes and interfaces in order to prepare a Builder Pattern for this pizza restaurant.
• A product interface which represents food products such as pizzas and drinks.
• A Wrapping interface which represents packaging of the food items
• The concrete classes which implement the product and Wrapping interfaces.
• The classes which implement the Wrapping interface as pizza would be packed in wrapped package and drink would be packed as a drink glass.
• A LunchMeal class that has an ArrayList of products.
• A LunchMealBuilder class to build different types of LunchMeal objects by combining products such as Veggie pizza with Mineral water, Veggie pizza with Soda drink, etc.
• A BuilderPatternDemonstration class which will use the LunchMealBuilder class to build a LunchMeal and generate the final bill along with the GST charges.
In the following example, we have demonstrated the above steps to explain the builder pattern in a very simple way.
Step 1: – Creation of an interface Product that represents the food and its wrapping.
Product.java
package com.eduonix.design.pattern.product; /** * * @author Aparajita * */ public interface Product { public String productName(); public Wrapping productWrap(); public float productPrice(); }
Wrapping.java
package com.eduonix.design.pattern.product; /** * * @author Aparajita * */ public interface Wrapping { public String wrap(); }
Step 2: – Creation of the concrete classes which implement the Wrapping interface.
PanTray.java
package com.eduonix.design.pattern.pizza; import com.eduonix.design.pattern.product.Wrapping; /** * * @author Aparajita * */ public class PanTray implements Wrapping { @Override public String wrap() { return "Presenting Pan tray!"; } }
DrinkGlass.java
package com.eduonix.design.pattern.drink; import com.eduonix.design.pattern.product.Wrapping; /** * * @author Aparajita * */ public class DrinkGlass implements Wrapping { @Override public String wrap() { return "Glass Drink!"; } }
Step 3: – Creation of the abstract classes which implement the product interface providing the default functionalities.
Pizza.java
package com.eduonix.design.pattern.pizza; import com.eduonix.design.pattern.product.Product; import com.eduonix.design.pattern.product.Wrapping; /** * * @author Aparajita * */ public abstract class Pizza implements Product{ @Override public Wrapping productWrap() { return new PanTray(); } @Override public abstract float productPrice(); }
Drink.java
package com.eduonix.design.pattern.drink; import com.eduonix.design.pattern.product.Product; import com.eduonix.design.pattern.product.Wrapping; /** * * @author Aparajita * */ public abstract class Drink implements Product { @Override public Wrapping productWrap() { return new DrinkGlass(); } @Override public abstract float productPrice(); }
Step 4: – Creation of the concrete classes extending Pizza and Drink classes.
VeggiePizza.java
package com.eduonix.design.pattern.pizza; /** * * @author Aparajita * */ public class VeggiePizza extends Pizza{ @Override public float productPrice() { return 12.99f; } @Override public String productName() { return "Veggie Pizza!"; } }
CheesePizza.java
package com.eduonix.design.pattern.pizza; /** * * @author Aparajita * */ public class ChessePizza extends Pizza{ @Override public float productPrice() { return 15.99f; } @Override public String productName() { return "Cheese Pizza!"; } }
MineralWater.java
package com.eduonix.design.pattern.drink; /** * * @author Aparajita * */ public class MineralWater extends Drink { @Override public float productPrice() { return 0.99f; } @Override public String productName() { return "Mineral Water!"; } }
SodaDrink.java
package com.eduonix.design.pattern.drink; /** * * @author Aparajita * */ public class SodaDrink extends Drink { @Override public float productPrice() { return 1.99f; } @Override public String productName() { return "Soda Drink!"; } }
Step 5: – Creation of a LunchMeal class which has these product objects.
LunchMeal.java
package com.eduonix.design.pattern.meal; import java.util.ArrayList; import java.util.List; import com.eduonix.design.pattern.product.Product; /** * * @author Aparajita * */ public class LunchMeal { private List<Product> products = new ArrayList<Product>(); public void addItem(Product product){ products.add(product); } public float getBill(){ float bill = 0.0f; for (Product product : products) { bill += product.productPrice(); } /** * GST Calculation 15% */ System.out.println("Applied GST is : $"+bill*0.15f); bill = bill*0.15f + bill; return bill; } public void showProducts(){ for (Product product : products) { System.out.print("Product : " + product.productName()); System.out.print(", Wrapping : " + product.productWrap().wrap()); System.out.println(", Price : $" + product.productPrice()); } } }
Step 6: – Creation of a LunchMealBuilder class which is the actual builder class accountable for the creation of LunchMeal objects.
LunchMealBuilder.java
package com.eduonix.design.pattern.meal; import com.eduonix.design.pattern.drink.MineralWater; import com.eduonix.design.pattern.drink.SodaDrink; import com.eduonix.design.pattern.pizza.ChessePizza; import com.eduonix.design.pattern.pizza.VeggiePizza; /** * * @author Aparajita * */ public class LunchMealBuilder { public LunchMeal prepareVeggiePizzaWithMineralWater() { LunchMeal LunchMeal = new LunchMeal(); LunchMeal.addItem(new VeggiePizza()); LunchMeal.addItem(new MineralWater()); return LunchMeal; } public LunchMeal prepareCheesePizzWithSodaDrink() { LunchMeal LunchMeal = new LunchMeal(); LunchMeal.addItem(new ChessePizza()); LunchMeal.addItem(new SodaDrink()); return LunchMeal; } public LunchMeal prepareVeggiePizzaWithSodaDrink() { LunchMeal LunchMeal = new LunchMeal(); LunchMeal.addItem(new VeggiePizza()); LunchMeal.addItem(new SodaDrink()); return LunchMeal; } public LunchMeal prepareCheesePizzWithMineralWater() { LunchMeal LunchMeal = new LunchMeal(); LunchMeal.addItem(new ChessePizza()); LunchMeal.addItem(new MineralWater()); return LunchMeal; } }
Step 7: – Creation of the BuiderPatternDemonstration class which uses LunchMealBuilder class to demonstrate the actual builder pattern.
BuiderPatternDemonstration.java
package com.eduonix.design.pattern; import com.eduonix.design.pattern.meal.LunchMeal; import com.eduonix.design.pattern.meal.LunchMealBuilder; /** * * @author Aparajita * */ public class BuilderPatternDemonstration { public static void main(String[] args) { LunchMealBuilder lunchMealBuilder = new LunchMealBuilder(); LunchMeal veggiePizzaMealMW = lunchMealBuilder.prepareVeggiePizzaWithMineralWater(); System.out.println("Veggie Pizza Meal with Mineral Water"); veggiePizzaMealMW.showProducts(); System.out.println("Total Bill: $" + veggiePizzaMealMW.getBill()); System.out.println("------------------------------"); LunchMeal veggiePizzaMealSD = lunchMealBuilder.prepareVeggiePizzaWithSodaDrink(); System.out.println("Veggie Pizza Meal with Soft Drink"); veggiePizzaMealSD.showProducts(); System.out.println("Total Bill: $" + veggiePizzaMealSD.getBill()); System.out.println("-----------------------------"); LunchMeal cheesePizzaMealMW = lunchMealBuilder.prepareCheesePizzWithMineralWater(); System.out.println("Cheese Pizza Meal with Mineral Water"); cheesePizzaMealMW.showProducts(); System.out.println("Total Bill: $" + cheesePizzaMealMW.getBill()); System.out.println("-----------------------------"); LunchMeal cheesePizzaMealSD = lunchMealBuilder.prepareCheesePizzWithSodaDrink(); System.out.println("Cheese Pizza Meal with Soda Drink"); cheesePizzaMealSD.showProducts(); System.out.println("Total Bill: $" + cheesePizzaMealSD.getBill()); System.out.println("-----------------------------"); } }
Output: – When we execute the above BuiderPatternDemonstration class as a Java Application, we can observe the following output.
Veggie Pizza Meal with Mineral Water Product : Veggie Pizza!, Wrapping : Presenting Pan tray!, Price : $12.99 Product : Mineral Water!, Wrapping : Glass Drink!, Price : $0.99 Applied GST is : $2.0970001 Total Bill: $16.077 ------------------------------ Veggie Pizza Meal with Soft Drink Product : Veggie Pizza!, Wrapping : Presenting Pan tray!, Price : $12.99 Product : Soda Drink!, Wrapping : Glass Drink!, Price : $1.99 Applied GST is : $2.247 Total Bill: $17.227 ----------------------------- Cheese Pizza Meal with Mineral Water Product : Cheese Pizza!, Wrapping : Presenting Pan tray!, Price : $15.99 Product : Mineral Water!, Wrapping : Glass Drink!, Price : $0.99 Applied GST is : $2.547 Total Bill: $19.527 ----------------------------- Cheese Pizza Meal with Soda Drink Product : Cheese Pizza!, Wrapping : Presenting Pan tray!, Price : $15.99 Product : Soda Drink!, Wrapping : Glass Drink!, Price : $1.99 Applied GST is : $2.697 Total Bill: $20.677
Source code for builder pattern in Java & J2EE
Conclusion: –
In this chapter, we discussed the builder pattern in detail along with suitable examples. In the example, we have demonstrated the building of a complex object from the simple objects through a step by step approach.
Informative and Insightful blog!
You have provided a great insight here about builder design pattern in java. Designer pattern allows to develop complicated object phase by phase and also makes sure a way to develop an object as a finished object. It is very helpful for all java developers to know about builder pattern in java, i have enjoyed this blog, thanks a lot for sharing!