Implementing Builder Design Pattern in PHP

Kartik MehtaKartik Mehta
5 min read

Introduction

The Builder Design Pattern is one of the most widely used design patterns in software development. This pattern allows developers to construct complex objects step by step, providing more control over the creation process. In this blog, we will explore the Builder Design Pattern in PHP, understand its components, and demonstrate its implementation with detailed code snippets. By the end of this blog, you will have a solid understanding of the Builder Design Pattern and how to use it effectively in your PHP projects. Additionally, we will create a mini-project to put our knowledge into practice.

What is the Builder Design Pattern?

The Builder Design Pattern is a creational pattern that allows for the step-by-step construction of complex objects. It separates the construction of a complex object from its representation, enabling the same construction process to create different representations.

Components of the Builder Design Pattern

The Builder Design Pattern consists of four main components:

  1. Product: The complex object that is being constructed.

  2. Builder Interface: An interface that defines the construction steps.

  3. Concrete Builder: Implements the Builder interface and constructs the product.

  4. Director: Controls the construction process using a Builder object.

When to Use the Builder Design Pattern

Use the Builder Design Pattern when:

  1. The construction process of an object is complex and involves multiple steps.

  2. Different representations of the object need to be created using the same construction process.

  3. The construction process needs to be independent of the parts that make up the object.

Implementing the Builder Design Pattern in PHP

Let's implement the Builder Design Pattern in PHP with a practical example. We will create a simple project to demonstrate the process of building a computer system step by step.

Creating the Product Class

First, we define the Product class, which represents the complex object being built. In this case, the Product class is a Computer class.

class Computer {
    private $cpu;
    private $ram;
    private $storage;
    private $graphicsCard;
    private $powerSupply;
    private $motherboard;

    public function setCpu($cpu) {
        $this->cpu = $cpu;
    }

    public function setRam($ram) {
        $this->ram = $ram;
    }

    public function setStorage($storage) {
        $this->storage = $storage;
    }

    public function setGraphicsCard($graphicsCard) {
        $this->graphicsCard = $graphicsCard;
    }

    public function setPowerSupply($powerSupply) {
        $this->powerSupply = $powerSupply;
    }

    public function setMotherboard($motherboard) {
        $this->motherboard = $motherboard;
    }

    public function __toString() {
        return "Computer Specifications: \n" .
               "CPU: " . $this->cpu . "\n" .
               "RAM: " . $this->ram . "\n" .
               "Storage: " . $this->storage . "\n" .
               "Graphics Card: " . $this->graphicsCard . "\n" .
               "Power Supply: " . $this->powerSupply . "\n" .
               "Motherboard: " . $this->motherboard . "\n";
    }
}

Defining the Builder Interface

Next, we define the Builder interface. This interface specifies the steps required to build the product.

interface ComputerBuilder {
    public function addCpu();
    public function addRam();
    public function addStorage();
    public function addGraphicsCard();
    public function addPowerSupply();
    public function addMotherboard();
    public function getComputer(): Computer;
}

Implementing Concrete Builder Classes

Now, we implement the Concrete Builder class. This class constructs the product by implementing the Builder interface.

class GamingComputerBuilder implements ComputerBuilder {
    private $computer;

    public function __construct() {
        $this->computer = new Computer();
    }

    public function addCpu() {
        $this->computer->setCpu("Intel i9-11900K");
    }

    public function addRam() {
        $this->computer->setRam("32GB DDR4");
    }

    public function addStorage() {
        $this->computer->setStorage("1TB NVMe SSD");
    }

    public function addGraphicsCard() {
        $this->computer->setGraphicsCard("NVIDIA RTX 3080");
    }

    public function addPowerSupply() {
        $this->computer->setPowerSupply("750W Gold");
    }

    public function addMotherboard() {
        $this->computer->setMotherboard("ASUS ROG Maximus XIII Hero");
    }

    public function getComputer(): Computer {
        return $this->computer;
    }
}

Creating the Director Class

The Director class controls the construction process using a Builder object.

class ComputerDirector {
    private $builder;

    public function setBuilder(ComputerBuilder $builder) {
        $this->builder = $builder;
    }

    public function buildComputer() {
        $this->builder->addCpu();
        $this->builder->addRam();
        $this->builder->addStorage();
        $this->builder->addGraphicsCard();
        $this->builder->addPowerSupply();
        $this->builder->addMotherboard();
    }
}

Mini Project: Building a Computer System

To solidify our understanding, let's create a mini-project that uses the Builder Design Pattern to build different types of computer systems. We will create three types of computers: GamingComputer, OfficeComputer, and ServerComputer.

Office Computer Builder

class OfficeComputerBuilder implements ComputerBuilder {
    private $computer;

    public function __construct() {
        $this->computer = new Computer();
    }

    public function addCpu() {
        $this->computer->setCpu("Intel i5-10400");
    }

    public function addRam() {
        $this->computer->setRam("16GB DDR4");
    }

    public function addStorage() {
        $this->computer->setStorage("512GB SSD");
    }

    public function addGraphicsCard() {
        $this->computer->setGraphicsCard("Integrated Graphics");
    }

    public function addPowerSupply() {
        $this->computer->setPowerSupply("500W Bronze");
    }

    public function addMotherboard() {
        $this->computer->setMotherboard("MSI B460M PRO-VDH");
    }

    public function getComputer(): Computer {
        return $this->computer;
    }
}

Server Computer Builder

class ServerComputerBuilder implements ComputerBuilder {
    private $computer;

    public function __construct() {
        $this->computer = new Computer();
    }

    public function addCpu() {
        $this->computer->setCpu("AMD EPYC 7742");
    }

    public function addRam() {
        $this->computer->setRam("128GB DDR4 ECC");
    }

    public function addStorage() {
        $this->computer->setStorage("2TB NVMe SSD");
    }

    public function addGraphicsCard() {
        $this->computer->setGraphicsCard("None");
    }

    public function addPowerSupply() {
        $this->computer->setPowerSupply("1200W Platinum");
    }

    public function addMotherboard() {
        $this->computer->setMotherboard("Supermicro H11DSi-NT");
    }

    public function getComputer(): Computer {
        return $this->computer;
    }
}

Main Program

Finally, let's create the main program to build different types of computers using the Builder Design Pattern.

// Autoload classes
spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

// Create Director
$director = new ComputerDirector();

// Build Gaming Computer
$gamingBuilder = new GamingComputerBuilder();
$director->setBuilder($gamingBuilder);
$director->buildComputer();
$gamingComputer = $gamingBuilder->getComputer();
echo $gamingComputer;

// Build Office Computer
$officeBuilder = new OfficeComputerBuilder();
$director->setBuilder($officeBuilder);
$director->buildComputer();
$officeComputer = $officeBuilder->getComputer();
echo $officeComputer;

// Build Server Computer
$serverBuilder = new ServerComputerBuilder();
$director->setBuilder($serverBuilder);
$director->buildComputer();
$serverComputer = $serverBuilder->getComputer();
echo $serverComputer;

Conclusion

The Builder Design Pattern is a powerful tool for constructing complex objects step by step. By separating the construction process from the representation, it provides flexibility and control over the object creation process. In this blog, we explored the components of the Builder Design Pattern, implemented it in PHP, and created a mini-project to build different types of computer systems. With this knowledge, you can now apply the Builder Design Pattern to your PHP projects and enhance the flexibility and maintainability of your code.

By understanding and implementing the Builder Design Pattern, you are equipped with a valuable design tool that can simplify the creation of complex objects and improve the structure of your code. Happy coding!

0
Subscribe to my newsletter

Read articles from Kartik Mehta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kartik Mehta
Kartik Mehta

A code dependent life form.