2.8. Fluent Interface
2.8.1. Purpose
To write code that is easy readable just like sentences in a natural language (like English).
2.8.2. Examples
Doctrine2’s QueryBuilder works something like that example class below
PHPUnit uses fluent interfaces to build mock objects
2.8.3. UML Diagram
2.8.4. Code
You can also find this code on GitHub
Sql.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\FluentInterface;
6
7class Sql implements \Stringable
8{
9 private array $fields = [];
10 private array $from = [];
11 private array $where = [];
12
13 public function select(array $fields): Sql
14 {
15 $this->fields = $fields;
16
17 return $this;
18 }
19
20 public function from(string $table, string $alias): Sql
21 {
22 $this->from[] = $table . ' AS ' . $alias;
23
24 return $this;
25 }
26
27 public function where(string $condition): Sql
28 {
29 $this->where[] = $condition;
30
31 return $this;
32 }
33
34 public function __toString(): string
35 {
36 return sprintf(
37 'SELECT %s FROM %s WHERE %s',
38 join(', ', $this->fields),
39 join(', ', $this->from),
40 join(' AND ', $this->where)
41 );
42 }
43}
2.8.5. Test
Tests/FluentInterfaceTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\FluentInterface\Tests;
6
7use DesignPatterns\Structural\FluentInterface\Sql;
8use PHPUnit\Framework\TestCase;
9
10class FluentInterfaceTest extends TestCase
11{
12 public function testBuildSQL()
13 {
14 $query = (new Sql())
15 ->select(['foo', 'bar'])
16 ->from('foobar', 'f')
17 ->where('f.bar = ?');
18
19 $this->assertSame('SELECT foo, bar FROM foobar AS f WHERE f.bar = ?', (string) $query);
20 }
21}