← Back to PatternPip

BUILDER / PRACTICE

One meal.
Built one choice at a time.

You met Builder while creating reports. Now apply it to a meal-ordering flow.

YOUR BRIEF

The order arrives in steps.

A customer chooses a base, then a main, then optional toppings. Keep those choices while the order is incomplete. Only return a meal when the required choices exist.

A finished meal must not change when the builder is edited later. Finally, turn a popular lunch combination into a reusable recipe.

The working starting point

const meal: Meal = {
  base: "Rice", main: "Tofu", toppings: ["Sesame"],
};

This is enough when all choices are available at once. The new requirement is a draft that grows over several steps, followed by a deliberate build boundary.

01 / ASSEMBLE

Turn choices into a finished meal.

Decide how steps retain the draft, when to validate it, and what leaves the builder.

Your assembled code

TypeScript preview. Highlighting follows the selected execution.

The finished meal

type Meal = Readonly<{
  base: string; main: string; toppings: readonly string[];
}>;

Builder · work in progress

class MealBuilder {
  private draft = { base: "", main: "", toppings: [] as string[] };

Builder · withBase

  // Choose what construction steps return.

Builder · withMain

  // Choose what construction steps return.

Builder · optional toppings

  // Choose what construction steps return.

Builder · validation and product creation

  build(): Meal {
    // Choose build-time validation.
    // Choose what build() returns.
  }
}

Caller · the selected test

// Complete the assembly before running a test.

02 / RUN & OBSERVE

What leaves the builder?

Build Rice + Tofu with Sesame. The finished meal should contain all three choices.

Builder · editable draft
Base
Not chosen
Main
Not chosen
Toppings
None
build() · draft becomes a product
First meal

Not built yet

Ready to test your assembly. Watch the draft grow, then compare it with the finished meal.

Your result and explanation will appear here.

  • ○ Build a complete meal — run to verify
  • ○ Try a meal without a main — run to verify
  • ○ Edit the builder after building — run to verify

Each test starts with a fresh builder. In the reuse test, both meals come from the same builder, which keeps its draft after build(). The animation follows the results of your selected methods.

03 / TRANSFER THE IDEA

The same lunch, ordered again.

A popular lunch always uses Rice, Beans, Corn and Chili. Add a reusable recipe so callers do not repeat the construction steps.

This recipe plays the optional Director role: it coordinates existing steps. The builder still owns the draft, validation and product creation.

First pass all three test cases with the same assembly.

Select all required edits

Compare with a complete solution

No timer and no attempt limit. Try another assembly, use a hint, or reveal the answer when it helps.