Easy Tutorial
❮ Null Object Pattern Abstract Factory Pattern ❯

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".

  1. StringBuilder in JAVA.

Advantages: 1. Builders are independent and easy to extend.

  1. Easy to control detailed risk.

Disadvantages: 1. Products must have commonalities with limited scope.

  1. If internal changes are complex, many builder classes will be needed.

Usage Scenarios: 1. Objects that need to be generated have complex internal structures.

  1. 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

Related Articles

❮ Null Object Pattern Abstract Factory Pattern ❯