Builder Pattern

[tr] Türkçe Oku

2023-06-11

Once upon a time, there was a very beautiful kingdom, and its name was “Builder Pattern”. Everything in this kingdom was about the art of constructing complex objects step by step and connecting them together. These complex objects were the most valuable treasures of the kingdom, and each one was carefully and thoughtfully constructed.

The wisest person in the kingdom was this master named the Builder. The Builder would construct complex objects using materials like stones, bricks, and wood. But the Builder didn’t do everything on his own. He had a Director to assist him. The Director would tell the Builder which parts to construct in what order. This way, the Director made sure that the Builder could focus solely on the construction of the object.

This story is implemented in the C# language as follows:

public interface IBuilder
{
    void BuildPartA();
    void BuildPartB();
    void BuildPartC();
}

public class ConcreteBuilder : IBuilder
{
    public void BuildPartA()
    {
        // Build PartA
    }

    public void BuildPartB()
    {
        // Build PartB
    }

    public void BuildPartC()
    {
        // Build PartC
    }
}

public class Director
{
    public void Construct(IBuilder builder)
    {
        builder.BuildPartA();
        builder.BuildPartB();
        builder.BuildPartC();
    }
}

The same story in Java:

public interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
}

public class ConcreteBuilder implements Builder {
    public void buildPartA() {
        // Build PartA
    }
    public void buildPartB() {
        // Build PartB
    }
    public void buildPartC() {
        // Build PartC
    }
}

public class Director {
    public void construct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
    }
}

In Python:

from abc import ABC, abstractmethod

class Builder(ABC):
    @abstractmethod
    def build_part_a(self):
        pass

    @abstractmethod
    def build_part_b(self):
        pass

    @abstractmethod
    def build_part_c(self):
        pass

class ConcreteBuilder(Builder):
    def build_part_a(self):
        # Build PartA
        pass

    def build_part_b(self):
        # Build PartB
        pass

    def build_part_c(self):
        # Build PartC
        pass

class Director:
    def construct(self, builder):
        builder.build_part_a()
        builder.build_part_b()
        builder.build_part_c()

In Go:

type Builder interface {
	BuildPartA()
	BuildPartB()
	BuildPartC()
}

type ConcreteBuilder struct{}

func (b *ConcreteBuilder) BuildPartA() {
	// Build PartA
}

func (b *ConcreteBuilder) BuildPartB() {
	// Build PartB
}

func (b *ConcreteBuilder) BuildPartC() {
	// Build PartC
}

type Director struct{}

func (d *Director) Construct(builder Builder) {
	builder.BuildPartA()
	builder.BuildPartB()
	builder.BuildPartC()
}

And in Rust:

pub trait Builder {
    fn build_part_a(&mut self);
    fn build_part_b(&mut self);
    fn build_part_c(&mut self);
}

pub struct ConcreteBuilder;

impl Builder for ConcreteBuilder {
    fn build_part_a(&mut self) {
        // Build PartA
    }
    fn build_part_b(&mut self) {
        // Build PartB
    }
    fn build_part_c(&

mut self) {
        // Build PartC
    }
}

pub struct Director;

impl Director {
    pub fn construct(&self, builder: &mut dyn Builder) {
        builder.build_part_a();
        builder.build_part_b();
        builder.build_part_c();
    }
}

And thus, we saw how the Builder and the Director constructed these complex objects. Building each part separately and in order was critical for the final form of the object. Also, the presence of the Director helps determine how and in what order the Builder should work. This makes the code more orderly, understandable, and flexible because we can create different objects using different Builders. This story demonstrates how the Builder design pattern works and how it can be used. This pattern provides a way to construct complex objects and facilitates the maintenance and extendability of the code.



More posts like this

The Dance of Components: The Composite Design Pattern

2023-06-22 | #composite-pattern #design-patterns #structural-patterns

Once upon a time, there was a tree in a forest. This tree was a complex structure with leaves and branches. Each branch could have smaller branches and leaves on it. The tree worked as a whole, holding its branches and leaves together. This tree is an example of the Composite design pattern. The tree (Composite) contains two types of components: branches (also Composite) and leaves (Leaf). Both branches and leaves implement the same interface (Component) recognized by the tree.

Continue reading 


Gaining Flexibility by Building Bridges: Analysis and Implementations in Four Different Languages with the Bridge Design Pattern

2023-06-22 | #bridge-pattern #design-patterns #structural-patterns

Once upon a time, there were two kingdoms. Despite being very close to each other, a wide and deep river was located between them. This river made it difficult for the kingdoms to interact with each other. To solve this situation, both kingdoms decided to build a bridge. This bridge became an interface that facilitated communication between the two kingdoms. However, the bridge had different structures and features on each side.

Continue reading 


Decorator Design Pattern: The Adornments of Software

2023-06-15 | #decorator-pattern #design-patterns #structural-patterns

Once upon a time, there was an object named “Component”. This object was used to perform a specific function. However, sometimes it was necessary to extend or modify this function. That’s where “Decorators” came into play. Decorators are objects that “decorate” or extend the Component. A Decorator comes on top of a Component and extends or modifies its function. This is used to extend the functionality of the Component without changing it itself.

Continue reading 