Builder
8/8/25About 1 min
Description
Builder is a creational design pattern, which allows constructing complex objects step by step.
- Xây dụng 1 đối tượng phức tạp bằng cách xử dụng các đối tượng đơn giản theo từng step.
- Các đối tượng độc lập với nhau.
Example
Build query của mysql
interface SQLQueryFactory
{
public function getSQLBuilder(): SQLQueryBuilder;
}
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;
// +100 other SQL syntax methods...
public function getSQL(): string;
}
class MySQLQueryFactory implements SQLQueryFactory
{
public function getSQLBuilder(): SQLQueryBuilder
{
return new MySQLQueryBuilder();
}
}
class MySQLQueryBuilder implements SQLQueryBuilder
{
protected \stdClass $query;
protected function reset(): void
{
$this->query = new \stdClass();
}
/**
* Build a base SELECT query.
* @param string $table
* @param array $fields
* @return SQLQueryBuilder
*/
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.
*
* @param string $field
* @param string $value
* @param string $operator
* @return SQLQueryBuilder
* @throws \Exception
*/
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.
*
* @param int $start
* @param int $offset
* @return SQLQueryBuilder
* @throws \Exception
*/
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;
}
}
Usage:
$mysqlFactory = new MySQLQueryFactory();
$builder = $mysqlFactory->getSQLBuilder();
$usersQuery = $builder
->select('users', ['*'])
->where('active', true)
->limit(0, 10)
->getSQL();
- Create query theo từng step thay vì xử lí cùng lúc tất cả tham số (select, limit, where, ..)
- Dễ test, maintaince.
Refer: https://refactoring.guru/design-patterns/builder/php/example#example-1