Builder Design Pattern in Ruby

1. Definition

The Builder Design Pattern separates the construction of a complex object from its representation. It allows the same construction process to create different representations.

2. Problem Statement

Consider the scenario where you need to construct a complex meal, which may have multiple courses, each with different items. Directly constructing such a complex object in a single step can be cumbersome and may lead to a tangled constructor with numerous parameters.

3. Solution

The Builder Pattern suggests moving the construction logic out of the main class and delegating it to separate objects called builders. The original class, known as the "director", controls the construction process and specifies which steps should be taken.

4. Real-World Use Cases

1. Constructing complex meals in a restaurant system.

2. Building different types of reports with varying data and layouts.

3. Creating intricate 3D models in a gaming system.

5. Implementation Steps

1. Define an abstract Builder interface that specifies steps to construct parts of a product.

2. Create concrete builder classes for different variants of the product.

3. Define a director class that constructs the product using the builder's methods.

4. The client uses the director and the builder to produce the desired variant of the product.

6. Implementation in Ruby

# Step 1: Builder interface class MealBuilder def add_starter; end def add_main_course; end def add_dessert; end def get_meal; end end # Step 2: Concrete builders class VegMealBuilder < MealBuilder def initialize @meal = [] end def add_starter @meal << "Veg Salad" end def add_main_course @meal << "Veg Curry" end def add_dessert @meal << "Fruit Salad" end def get_meal @meal.join(", ") end end class NonVegMealBuilder < MealBuilder def initialize @meal = [] end def add_starter @meal << "Chicken Salad" end def add_main_course @meal << "Grilled Chicken" end def add_dessert @meal << "Ice Cream" end def get_meal @meal.join(", ") end end # Step 3: Director class Chef def prepare_veg_meal(builder) builder.add_starter builder.add_main_course builder.add_dessert builder.get_meal end def prepare_non_veg_meal(builder) builder.add_starter builder.add_main_course builder.add_dessert builder.get_meal end end # Client code chef = Chef.new veg_builder = VegMealBuilder.new puts chef.prepare_veg_meal(veg_builder) non_veg_builder = NonVegMealBuilder.new puts chef.prepare_non_veg_meal(non_veg_builder) 

Output:

Veg Salad, Veg Curry, Fruit Salad Chicken Salad, Grilled Chicken, Ice Cream 

Explanation:

1. The MealBuilder class defines the abstract builder interface with methods to add different courses and get the meal.

2. VegMealBuilder and NonVegMealBuilder are concrete builders implementing the builder interface.

3. The Chef class acts as the director and uses a builder to construct meals.

4. The client code creates instances of the director and builders producing the desired type of meal.

7. When to use?

Use the Builder pattern when:

1. The algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled.

2. The construction process must allow different representations of the object being built.

3. The product's construction involves multiple steps, which might require different product configurations.


Comments