Hai teman-teman setelah sebelumnya kita telah pendahuluan tentang pembahasan Cara Menggunakan Singleton Pattern Di PHP Dan sekarang kita akan memulai dengan salah satu design pattern yang sering sekali di implementasikan pada framework PHP yaitu Cara Menggunakan Builder Pattern Di PHP. 

Builder Pattern merupakan pattern yang terkenal di dunia PHP. Ini sangat berguna ketika kita perlu membuat objek dengan banyak opsi konfigurasi yang memungkinkan. Misalnya jika teman-teman menggunakan framework CODEIGNITER ATAU LARAVEL  di kedua framework tersebut ada yang namanya QUERY BUILDER betul tidak ?

Nah QUERY BUILDER tersebut sebetulnya di buat menggunakan konsep dari builder pattern tetapi dengan konfigurasi yang sangat banyak dan kompleks,  Pada artikel kali ini kita akan membuat QUERY BUILDER kita sendiri tetapi hanya sederhana saja dan sebagai gambaran konsep dari builder pattern itu sendiri.

Pada dasarnya Builder Pattern adalah cara dimana kita memisahkan cara pembuatan sebuah object dari class objectnya itu sendiri, Maksudnya seperti apa ?

Biasanya ketika kita membuat sebuah class dan untuk membuat objectnya yang kita lakukan adalah buat object nya dengan memanfaatkan magic method __construct atau sebuah constructor diamana pembuatan objectnya di lakukan di class obejct nya itu sendiri, nah Builder pattern ini memisahkan anara class dengan class objectnya itu sendiri. Kita langsung saja buat contohnya :

Salah satu aplikasi terbaik dari pattern Builder adalah pembangun query SQL. Antarmuka pembangun mendefinisikan langkah-langkah umum yang diperlukan untuk membangun kueri SQL generik. Seabgai contoh :

Pertama-tama kita buat root projectnya tersebih dahulu dengan nama BUILDER lalu di dalam folder tersebut kita buat folder baru dengan nama Classes jadi BUILDER => Classes 

Setelah itu kita buat 1 class interfacenya di dalam folder Classes dengan nama SQLQueryBuilder.php jadi seperti ini Classes => SQLQueryBuilder :

 

<?php 

namespace Classes;

interface SQLQueryBuilder
{
    public function select(string $table, array $fields): SQLQueryBuilder;

    public function where(string $field, string $value, string $operator = '='): SQLQueryBuilder;

    public function limit(int $start, int $offset): SQLQueryBuilder;

    public function getSQL(): string;
}

Dan untuk selanjutnya kita buat Class baru untuk mengimplementasikan semua interface yang baru saja kita buat pada class interface.  Silahkan buat file dengan nama MysqlQueryBuilder dan isinya adalah perintah pembuatan query dengan memanfaatkan interface yang kita buat sebelumnya.

<?php

namespace Classes;

use Classes\SQLQueryBuilder;

class MysqlQueryBuilder implements SQLQueryBuilder
{
    protected $query;

    protected function reset(): void
    {
        $this->query = new \stdClass;
    }

    /**
     * Build a base SELECT query.
     */
    public function select(string $table, array $fields): SQLQueryBuilder
    {
        $this->reset();
        $this->query->base = "SELECT " . implode(", ", $fields) . " FROM " . $table;
        $this->query->type = 'select';

        return $this;
    }

    /**
     * Add a WHERE condition.
     */
    public function where(string $field, string $value, string $operator = '='): SQLQueryBuilder
    {
        if (!in_array($this->query->type, ['select', 'update', 'delete'])) {
            throw new \Exception("WHERE can only be added to SELECT, UPDATE OR DELETE");
        }
        $this->query->where[] = "$field $operator '$value'";

        return $this;
    }

    /**
     * Add a LIMIT constraint.
     */
    public function limit(int $start, int $offset): SQLQueryBuilder
    {
        if (!in_array($this->query->type, ['select'])) {
            throw new \Exception("LIMIT can only be added to SELECT");
        }
        $this->query->limit = " LIMIT " . $start . ", " . $offset;

        return $this;
    }

    /**
     * Get the final query string.
     */
    public function getSQL(): string
    {
        $query = $this->query;
        $sql = $query->base;
        if (!empty($query->where)) {
            $sql .= " WHERE " . implode(' AND ', $query->where);
        }
        if (isset($query->limit)) {
            $sql .= $query->limit;
        }
        $sql .= ";";
        return $sql;
    }
}

Setelah kita membuat class interface dan class buildernya saatnya kita gunakan pada class kita masing-masing, dan untuk menggunakan Builder tersebut pada client/user dengan cara seperti ini :

<?php 

use Classes\SQLQueryBuilder;

class CustomerController 
{
    function getUser(SQLQueryBuilder $queryBuilder)
    {
        $query = $queryBuilder
            ->select("users", ["name", "email", "password"])
            ->where("age", 18, ">")
            ->where("age", 30, "<")
            ->limit(10, 20)
            ->getSQL();

        echo $query;
    }
}

Pasti teman-teman udah familiar banget kan dengan code di atas ? Yupss bagi teman-teman yang menggunakan framework CI ata Laravel pasti pernah menggunakan query builder tetapi masih terbatas pakai saja dan tidak tahu sebetulnya cara kerjanya seperti di atas kurang lebih bergantung kompleksitas dan style dari programmernya.