Tuesday, October 8, 2024

Builder Pattern

 

Design pattern Builder adalah design pattern yang memberikan solusi fleksibel terhadap berbagai masalah pembuatan object dalam object-oriented programming (OOP). Builder pattern memisahkan konstruksi object yang kompleks dari representasinya.

Sederhananya, Builder pattern memisahkan cara pembuatan object dari sebuah class dengan cara tidak membuat instance object secara langsung menggunakan constructor dari class tersebut. Jadi, kita akan membuat suatu class baru yang dikhususkan untuk membuat object dari sebuah class.

Contoh sederhananya, kita punya sebuah class yang bernama class Employee. Ketika kita ingin menggunakan class tersebut, kita tidak akan langsung membuat instance dari class tersebut, akan tetapi kita akan membuat class baru bernama EmployeeBuilder yang dikhususkan untuk membuat object dari class Employee.


1. Contoh class yang akan kita implementasi dengan design pattern Builder

* PHP yang saya gunakan adalah PHP versi 8.3

Praktiknya, disini kita punya sebuah class bernama Employee,

<?php

namespace Pattern\Builder;

class Employee
{
/**
* @var int ID Employee
*/
private int $id;

/**
* @var string First Name
*/
private string $firstName;

/**
* @var string Last Name
*/
private string $lastName;

/**
* @var string Email
*/
private string $email;

/**
* @var string Phone
*/
private string $phone;

/**
* Employee constructor
* @param int $id
* @param string $firstName
* @param string $lastName
* @param string $email
* @param string $phone
*/

public function __construct(
int $id,
string $firstName,
string $lastName,
string $email,
string $phone
) {
$this->id = $id;
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->email = $email;
$this->phone = $phone;
}

/**
* get the ID number of the employee
*
* @return int $id
*/
public function getId(): int
{
return $this->id;
}

/**
* Get the full name of the employee
*
* @return string $firstName + $lastName
*/
public function getFullName(): string
{
return $this->firstName . " " . $this->lastName;
}

/**
* Get the email of the employee
*
* @return string $email
*/
public function getEmail(): string
{
return $this->email;
}

/**
* Get the phone number of the employee
*
* @return string $phone
*/
public function getPhone(): string
{
return $this->phone;
}
}


Ketika kita ingin membuat object dari class Employee di atas, simple saja kita akan melakukan inisialisasi seperti di bawah ini,

<?php

namespace Pattern;

require 'vendor/autoload.php';

use Pattern\Builder\Employee;

/* Membuat Object tanpa menggunakan Builder */
$employee = new Employee(1, "Supriadi", "Ahmad", "supriadi@mail.com", "0871234567");

print_r($employee);
echo "ID: " . $employee->getId() . "\n";
echo "Full Name: " . $employee->getFullName() . "\n";
echo "Email: " . $employee->getEmail() . "\n";
echo "Phone: " . $employee->getPhone() . "\n";
echo "\n----------\n";

Namun, apabila suatu saat kita ingin menambahkan property baru pada class Employee, misalnya kita akan menambahkan property. Kita akan diharuskan untuk menyesuaikan semua kode class Employee yang ada di tiap file project kita dengan versi update terbaru dari class tersebut.

Jika kita mengubah kode inisialisai class Employe pada tiap file project kita, hal tersebut akan beresiko menyebabkan terjadinya error. Oleh karena itu, untuk menangani masalah tersebut kita akan membuat class baru bernama Employee Builder yang digunakan khusus untuk membuat object dari class Employee.

Dengan design pattern Builder, parameter pada class Employee akan kita buat menjadi opsional, sehingga ketika ada perubahan parameter atau property pada class Employe, kita tidak perlu merubah semua kode class Employee dan tidak perlu menyesuaikan kembali parameter ketika ada penambahan parameter baru.


2. Implementasi design pattern Builder pada class Employee

Disini kita akan mebuat class baru bernama EmployeeBuilder, seperti contoh di bawah ini,

<?php

namespace Pattern\Builder;

use Pattern\Builder\Employee;

class EmployeeBuilder
{
/**
* @var int ID
*/
private $id;

/**
* @var string First Name
*/
private string $firstName = "";

/**
* @var string Last Name
*/
private string $lastName = "";

/**
* @var string Email
*/
private string $email = "";

/**
* @var string Phone
*/
private string $phone = "";

/**
* set the ID number of the employee
*
* @param int $id
*
* @return object EmployeeBuilder
*/
public function setId(int $id): EmployeeBuilder
{
$this->id = $id;
return $this;
}

/**
* Set the first name of the employee
*
* @param string $firstName
*
* @return object EmployeeBuilder
*/
public function setFirstName(string $firstName): EmployeeBuilder
{
$this->firstName = $firstName;
return $this;
}

/**
* Set the last name of the employee
*
* @param string $lastName
*
* @return object EmployeeBuilder
*/
public function setLastName(string $lastName): EmployeeBuilder
{
$this->lastName = $lastName;
return $this;
}

/**
* Set the email of the employee
*
* @param string $email
*
* @return object EmployeeBuilder
*/
public function setEmail(string $email): EmployeeBuilder
{
$this->email = $email;
return $this;
}

/**
* Set the phone number of the employee
*
* @param string $phone
*
* @return object EmployeeBuilder
*/
public function setPhone(string $phone): EmployeeBuilder
{
$this->phone = $phone;
return $this;
}

/**
* Create an instance of the employee class
*
* @return object Employee
*/
public function build(): Employee
{
return new Employee(
$this->id,
$this->firstName,
$this->lastName,
$this->email,
$this->phone
);
}
}

Melalui class EmployeeBuilder inilah kita akan membuat sebuah object dari class Employee. 

Pada kode Builder di atas, class Builder memiliki property yang sama dengan class Employee yaitu id, firstName. lastName, email, dan phone dengan masing-masing property memiliki default value.

Pada bagian methods di class Builder, kita membuat method setId, setFirstName, setLastName, setEmail, dan setPhone untuk menginisialisasikan data pada masing-masing property class EmployeeBuilder. Tiap method melakukan "return this" atau mengembalikan dirinya sendiri (object EmployeBuilder), hal tersebut digunakan untuk membuat chaining method


3. Membuat object dari class Employee menggunakan class EmployeeBuilder

Karena kita telah membuat class Builder bernama EmployeeBuilder, sekarang kita akan menggunakan class tersebut untuk membuat object dari class Employee. Berikut adalah contoh inisialisasi object class Employee menggunakan class EmployeeBuilder,

<?php

namespace Pattern;

require 'vendor/autoload.php';

use Pattern\Builder\EmployeeBuilder;

/* Membuat Object menggunakan Builder */
$firstEmployee = (new EmployeeBuilder())
->setId(1)
->setFirstName("Andreas")
->setLastName("Pirlo")
->setEmail("andreas@mail.com")
->setPhone("085312234")
->build();

print_r($firstEmployee);
echo "ID: " . $firstEmployee->getId() . "\n";
echo "Full Name: " . $firstEmployee->getFullName() . "\n";
echo "Email: " . $firstEmployee->getEmail() . "\n";
echo "Phone: " . $firstEmployee->getPhone() . "\n";
echo "\n----------\n";

$secondEmployee = (new EmployeeBuilder())
->setId(1)
->setFirstName("Jamal")
->setLastName("Rodriguez")
->build();

print_r($secondEmployee);

Perhatikan pada variable $secondEmployee, karena kita menggunakan class Builder, maka kita tidak harus mendefinisikan semua nilai yang ada di parameter constructor class Employee, karena kita telah membuat default value untuk setiap property di class Employee pada class EmployeeBuilder. Selain itu, kita bisa memanggil method untuk set data secara berurutan atau chaining sesuai kebutuhan. 


Selesai.