CSC 207 Grinnell College Fall, 2018
 
Algorithms and Object-Oriented Design
 

Laboratory: the Builder Design Pattern

Summary

In this lab, you will get a concrete look at another example of the builder pattern Design Patterns Chapters 1–2).

Acknowledgment

Jerod Weinman wrote today's reading. Also, this lab is a lightly edited version of a lab, "Building the Builder", written by Jerod Weinmen.

Background

Today's reading mentions that the builder pattern is used when some type of composite "product" class must be constructed. There may also be an abstract class representing the generic notion of the operations required to build a particular type of product. Different sub-classes are used for the different, particular products. It is the responsibility of a "director" to explicitly build all the component's parts.

In this activity, we will follow an example of a fast food restaurant operation that builds your value meals (the product) on demand. Some fast food chains have pre-defined value meals that essentially let you, using an order-by-number scheme, choose predefined combinations of sandwich (or entree, more generically), fries (the side), and your soda (or drink).

Here is a class that models the product for us:

Meal.java

/**
 * Meal models a typical fast-food chain value meal consisting of an
 * entree, a side, and a drink. 
 */
public class Meal {
  
  private String entree = ""; /** Primary dish of this meal */
  private String side = "";   /** Side dish of this meal */
  private String drink = "";  /** Drink for this meal */

  /**
   * Set the entree of this meal to the specified value.
   *
   * @param entree Specified value to set the entree of this meal to
   */
  public void setEntree(String entree) { 
    this.entree = entree;
  }

  /**
   * Set the side dish of this meal to the specified value.
   *
   * @param entree Specified value to set the side dish of this meal to
   */
  public void setSide(String side) { 
    this.side = side;
  }

  /**
   * Set the drink of this meal to the specified value.
   *
   * @param entree Specified value to set the drink of this meal to
   */
  public void setDrink(String drink) {
    this.drink = drink;
  }

  /**
   * Return a string representation of this meal indicating all portions.
   *
   * @return a String indicating all portions this meal
   */
  public String toString() {
    return entree + " with a side of " + side + " and a " + drink;
  }
}
Note that there are three objects (in this case, Strings) that need to be "built" in order to have a complete meal.

Steps for this Lab

  1. As mentioned above, a builder pattern requires an abstract builder class. In the following exercises, you will declare and/or add some methods in the following abstract meal builder.

    MealBuilder.java

      /** Abstract builder for the Meal objects, supporting all the
     *  operations for building a meal.
     *
     * @author YOUR NAME HERE
     */
    public abstract class MealBuilder {
    
      protected Meal theMeal;
    
      // Additional methods here
    
    }
    
    1. First of all, notice that the meal is not initialized. Add a createMeal() method that creates a new "empty" meal object. (createMeal creates a new meal object that is stored as theMeal; createMeal takes no parameters and returns void.) Should this method be abstract or not?
    2. Once a (concrete) builder finishes building the meal, we need some way to retrieve it. Add a function Meal getMeal() that allows someone to retrieve the value meal after a (more concrete) builder finishes building it. Should this method be abstract or not?
    3. Now, we need to specify what operations any meal builder must implement. These correspond to the objects that must be constructed, which in our case are the three elements of the meal.

      Add three methods that will allow a concrete builder to "build" the three elements of the meal. Note: These functions should accept no arguments and return void.

      Should these methods be abstract or not?

  2. Our next step is to implement some concrete builders that actually put some food in your meal! Let's start with a typical fast food value meal.

    BurgerMealBuilder.java

    /** Concrete builder for a meal with a burger, fries, and a cola. */
    public class BurgerMealBuilder extends MealBuilder {
    
    }
    
    1. Add to BurgerMealBuilder the implementations of the three methods you defined in class MealBuilder that end up setting the entree to "Burger", the side to "Fries", and the drink to "Cola".
    2. Create a class called HealthyMealBuilder that builds a meal consisting of "Chicken Sandwich", "Carrot Sticks", and "Diet Cola".
  3. Our final step is the "director" that coordinates all the requisite action of the builders. Remember that a builder has methods that facilitate each step of the process, but it is the "director" (in our case a cook), that actually takes those steps!

    Cook.java

    /** A cook that uses a builder for a meal to actually construct a meal
     * and make it available.
     *
     * @author Jerod Weinman
     * @author YOUR NAME HERE
     */
    public class Cook {
    
      /** A meal builder that specifies how to assemble a particular meal */
      private MealBuilder builder; 
    
      
      /**
       * Set the meal builder for this cook to the specified value.
       *
       * @param builder the meal builder for this cook to use
       */
      public void setMealBuilder (MealBuilder builder) {
        this.builder = builder;
      }
    
      /**
       * Return the meal constructed by this cook.
       *
       * @return the meal constructed by this cook.
       */
      public Meal getMeal() {
        return builder.getMeal();
      }
    
      
      /**
       * Uses the meal builder of this cook to construct all portions of a meal.
       */
      public void constructMeal() {
        // Take the necessary steps
      }
    
    }
    
    
    1. Using the methods available in a MealBuilder object, add code to the constructMeal method above that (finally!) constructs the meal. You should have four function calls! (Don't forget about 1.a)
  4. If you have time, you should be able to test your fast food restaurant with the following code.

    BuilderExample.java

    /** A driver class for building some value meals 
     *
     * @author Jerod Weinman
     * @author revised by Henry M. Walker
     */
    public class BuilderExample {
    
      
      /**
       * A program that creates a cook and uses it with various meal builders
       * to construct meals.
       *
       * @param args unused command-line arguments
       */
      public static void main(String[] args) {
    
        Cook cook = new Cook();
        Meal meal1, meal2, meal3, meal4;
    
        MealBuilder burgerBuilder = new BurgerMealBuilder();
        MealBuilder healthyBuilder = new HealthyMealBuilder();
    
        cook.setMealBuilder (burgerBuilder);
        cook.constructMeal();
        meal1 = cook.getMeal();
    
        cook.setMealBuilder (healthyBuilder);
        cook.constructMeal();
        meal2 = cook.getMeal();
    
        cook.setMealBuilder (healthyBuilder);
        cook.constructMeal();
        meal3 = cook.getMeal();
    
        cook.setMealBuilder (burgerBuilder);
        cook.constructMeal();
        meal4 = cook.getMeal();
    
        System.out.println("Order up! A " + meal1);
        System.out.println("Order up! A " + meal2);
        System.out.println("Order up! A " + meal3);
        System.out.println("Order up! A " + meal4);
      }
    }
    
    
    Which should produce
    Order up! A burger with a side of fries and a cola
    Order up! A chicken sandwich with a side of carrot sticks and a diet cola
    Order up! A chicken sandwich with a side of carrot sticks and a diet cola
    Order up! A burger with a side of fries and a cola
    

http://www.walker.cs.grinnell.edu/courses/207.sp012/labs/lab-builder.shtml

created 6 January 2009 by Jerod Weinman
revised 17 January 2011 by Jerod Weinman
revised 18-22 February 2012 by Henry M. Walker
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.
Copyright © 2009-2011 Jerod Weinman.
CC-BY-NC-SA
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License .