Шаблон «Fluent interface» (Текучий интерфейс)
22-06-2019Reading time ~ 2 min.PHP/ООП 7027
Строго говоря, «Текучий интерфейс» даже не сколько паттерн, сколько методика организации кода, направленная на то, чтобы упростить его чтение. Вместо последовательных вызовов функций в каждой строчке, организуется цепочка методов. Наверняка вы с таким встречались:
$fullName = (new MyName())->setFirstName('Don')->setLastName('Joe')->getResult();
Реализуется такой подход очень просто. Каждый метотод, который может участвовать в цепочке, должен возвращать ссылку на свой объект $this
.
Посмотрите на код Fluent interface на гитхабе, чтобы понять общий принцип.
Применяется такой подход достаточно часто. Наверное самый красноречивый пример — это построение SQL-запросов с помощью цепочки вызовов, вроде такой:
$sql = $DB->select('')->from('')->where('')->order('')->getSql();
Fluent interface базируется на том, что в классе есть сеттеры (set) и геттеры (get). Первые обычно просто устанавливают значение какого-то поля класса.
public function setFirstName($name) { $this->firstName = $name; return $this; }
Вторые — получают результат.
public function getFirstName() { return $this->firstName; }
Так вот, у сеттеров можно возвращать $this
, а значит они могут не только участвовать в цепочке вызовов, но и обеспечивают её дальнейшее построение. А вот геттеры обычно завершают цепочку и возвращают какой-то свой конечный результат.
Ещё нужно учитывать, что последовательность вызовов может меняться. Если сеттер просто присваивает значение полю, то он может выполняться в любом месте. Но, если он ещё что-то делает, что может повлиять на остальные поля, то такой метод потребуется указывать в строго определенном месте. В этом случае такой метод лучше вызывать отдельно.