2.8. Fluent Interface
2.8.1. Purpose
To write code that is easy readable just like sentences in a naturallanguage (like English).
2.8.2. Examples
- Doctrine2’s QueryBuilder works something like that example classbelow
- PHPUnit uses fluent interfaces to build mock objects
- Yii Framework: CDbCommand and CActiveRecord use this pattern, too
2.8.3. UML Diagram
2.8.4. Code
You can also find this code on GitHub
Sql.php
- <?php
- namespace DesignPatterns\Structural\FluentInterface;
- class Sql
- {
- /**
- * @var array
- */
- private $fields = [];
- /**
- * @var array
- */
- private $from = [];
- /**
- * @var array
- */
- private $where = [];
- public function select(array $fields): Sql
- {
- $this->fields = $fields;
- return $this;
- }
- public function from(string $table, string $alias): Sql
- {
- $this->from[] = $table.' AS '.$alias;
- return $this;
- }
- public function where(string $condition): Sql
- {
- $this->where[] = $condition;
- return $this;
- }
- public function __toString(): string
- {
- return sprintf(
- 'SELECT %s FROM %s WHERE %s',
- join(', ', $this->fields),
- join(', ', $this->from),
- join(' AND ', $this->where)
- );
- }
- }
2.8.5. Test
Tests/FluentInterfaceTest.php
- <?php
- namespace DesignPatterns\Structural\FluentInterface\Tests;
- use DesignPatterns\Structural\FluentInterface\Sql;
- use PHPUnit\Framework\TestCase;
- class FluentInterfaceTest extends TestCase
- {
- public function testBuildSQL()
- {
- $query = (new Sql())
- ->select(['foo', 'bar'])
- ->from('foobar', 'f')
- ->where('f.bar = ?');
- $this->assertEquals('SELECT foo, bar FROM foobar AS f WHERE f.bar = ?', (string) $query);
- }
- }