Builder Pattern
The Builder Pattern uses multiple simple objects to construct a complex object step by step. This type of design pattern is a creational pattern that provides one of the best ways to create an object.
A Builder class constructs the final object step by step. This Builder class is independent of other objects.
Introduction
Intent: Separate the construction of a complex object from its representation so that the same construction process can create different representations.
Main Solution: Mainly solve the problem of creating a complex object in software systems, which is usually composed of sub-objects with certain algorithms; due to changing requirements, the various parts of this complex object often undergo drastic changes, but the algorithms that combine them are relatively stable.
When to Use: When some basic components do not change, but their combinations often do.
How to Solve: Separate the mutable from the immutable.
Key Code: Builder: creates and provides instances, Director: manages the dependency relationships of the constructed instances.
Application Examples: 1. Going to KFC, where burgers, cola, fries, fried chicken wings, etc., are constant, but their combinations often change, resulting in so-called "meals".
- StringBuilder in JAVA.
Advantages: 1. Builders are independent and easy to extend.
- Easy to control detailed risk.
Disadvantages: 1. Products must have commonalities with limited scope.
- If internal changes are complex, many builder classes will be needed.
Usage Scenarios: 1. Objects that need to be generated have complex internal structures.
- Objects that need to be generated have internal attributes that depend on each other.
Notes: The difference from the Factory Pattern is that the Builder Pattern pays more attention to the assembly sequence of parts.
Implementation
We assume a commercial case for a fast-food restaurant, where a typical meal can consist of a burger (Burger) and a cold drink (Cold drink). Burgers (Burger) can be vegetarian burgers (Veg Burger) or chicken burgers (Chicken Burger), packed in boxes. Cold drinks (Cold drink) can be Coca-Cola (coke) or Pepsi (pepsi), packed in bottles.
We will create an Item interface representing food items (such as burgers and cold drinks) and entity classes implementing the Item interface, as well as a Packing interface representing food packaging and entity classes implementing the Packing interface. Burgers are packed in boxes, and cold drinks are packed in bottles.
Then we create a Meal class with an ArrayList of Item and a MealBuilder that creates different types of Meal objects by combining Item. The BuilderPatternDemo class uses MealBuilder to create a Meal.
Step 1
Create an interface to represent food items and food packaging.
Item.java
public interface Item {
public String name();
public Packing packing();
public float price();
}
Packing.java
public interface Packing {
public String pack();
}
Step 2
Create entity classes implementing the Packing interface.
Wrapper.java
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
Bottle.java
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
Step 3
Create abstract classes implementing the Item interface that provide default functionalities.
Burger.java
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
ColdDrink.java
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
Step 4
Create concrete classes extending Burger and ColdDrink.
VegBurger.java
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
ChickenBurger.java
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
Coke.java
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
Pepsi.java
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
Step 5
Create a Meal class with the previously defined Item objects.
Meal.java
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
Step 6
Create a MealBuilder class, the actual builder class responsible for creating Meal objects.
MealBuilder.java
public class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
Step 7
BuilderPatternDemo uses MealBuilder to demonstrate the Builder Pattern.
BuilderPatternDemo.java
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
Step 8
Execute the program, output results:
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0
Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5