php_patterns
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| php_patterns [2021/07/07 05:42] – chifek | php_patterns [2023/09/14 06:06] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 169: | Line 169: | ||
| </ | </ | ||
| + | |||
| + | |||
| + | ===== Одиночка (Singleton) ===== | ||
| + | |||
| + | |||
| + | Наверное, | ||
| + | |||
| + | < | ||
| + | |||
| + | <?php | ||
| + | /** | ||
| + | * Одиночка | ||
| + | */ | ||
| + | final class Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var self | ||
| + | */ | ||
| + | private static $instance; | ||
| + | |||
| + | /** | ||
| + | * @var mixed | ||
| + | */ | ||
| + | public $a; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * Возвращает экземпляр себя | ||
| + | * | ||
| + | * @return self | ||
| + | */ | ||
| + | public static function getInstance() | ||
| + | { | ||
| + | if (!(self:: | ||
| + | self:: | ||
| + | } | ||
| + | return self:: | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Конструктор закрыт | ||
| + | */ | ||
| + | private function __construct() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Клонирование запрещено | ||
| + | */ | ||
| + | private function __clone() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Сериализация запрещена | ||
| + | */ | ||
| + | private function __sleep() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Десериализация запрещена | ||
| + | */ | ||
| + | private function __wakeup() | ||
| + | { | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $firstProduct = Product:: | ||
| + | $secondProduct = Product:: | ||
| + | |||
| + | $firstProduct-> | ||
| + | $secondProduct-> | ||
| + | |||
| + | print_r($firstProduct-> | ||
| + | // 2 | ||
| + | print_r($secondProduct-> | ||
| + | // 2 | ||
| + | |||
| + | </ | ||
| + | |||
| + | Принцип синглтона прост, как пять копеек. Для того, чтобы обеспечить существование только одного экземпляра класса Product, мы закрыли все магические методы для создания экземпляра класса, | ||
| + | |||
| + | Я добавил в класс открытое свойство $a, чтобы продемонстрировать работу одиночки. В данном примере можно увидеть, | ||
| + | |||
| + | |||
| + | ===== Пул одиночек (Multiton) ===== | ||
| + | |||
| + | |||
| + | Возможно, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Общий интерфейс пула одиночек | ||
| + | */ | ||
| + | abstract class FactoryAbstract | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var array | ||
| + | */ | ||
| + | protected static $instances = array(); | ||
| + | |||
| + | |||
| + | /** | ||
| + | * Возвращает экземпляр класса, | ||
| + | * | ||
| + | * @return static | ||
| + | */ | ||
| + | public static function getInstance() | ||
| + | { | ||
| + | $className = static:: | ||
| + | if (!(self:: | ||
| + | self:: | ||
| + | } | ||
| + | return self:: | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Удаляет экземпляр класса, | ||
| + | * | ||
| + | * @return void | ||
| + | */ | ||
| + | public static function removeInstance() | ||
| + | { | ||
| + | $className = static:: | ||
| + | if (array_key_exists($className, | ||
| + | unset(self:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Возвращает имя экземпляра класса | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | final protected static function getClassName() | ||
| + | { | ||
| + | return get_called_class(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Конструктор закрыт | ||
| + | */ | ||
| + | protected function __construct() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Клонирование запрещено | ||
| + | */ | ||
| + | final protected function __clone() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Сериализация запрещена | ||
| + | */ | ||
| + | final protected function __sleep() | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Десериализация запрещена | ||
| + | */ | ||
| + | final protected function __wakeup() | ||
| + | { | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Интерфейс пула одиночек | ||
| + | */ | ||
| + | abstract class Factory extends FactoryAbstract | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает экземпляр класса, | ||
| + | * | ||
| + | * @return static | ||
| + | */ | ||
| + | final public static function getInstance() | ||
| + | { | ||
| + | return parent:: | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Удаляет экземпляр класса, | ||
| + | * | ||
| + | * @return void | ||
| + | */ | ||
| + | final public static function removeInstance() | ||
| + | { | ||
| + | parent:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | /** | ||
| + | * Первый одиночка | ||
| + | */ | ||
| + | class FirstProduct extends Factory | ||
| + | { | ||
| + | public $a = []; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Второй одиночка | ||
| + | */ | ||
| + | class SecondProduct extends FirstProduct | ||
| + | { | ||
| + | } | ||
| + | |||
| + | // Заполняем свойства одиночек | ||
| + | FirstProduct:: | ||
| + | SecondProduct:: | ||
| + | FirstProduct:: | ||
| + | SecondProduct:: | ||
| + | |||
| + | print_r(FirstProduct:: | ||
| + | // array(1, 3) | ||
| + | print_r(SecondProduct:: | ||
| + | // array(2, 4) | ||
| + | </ | ||
| + | |||
| + | Итак, для добавления нового класса-одиночки нам просто нужно унаследовать его от класса Factory. В примере мы создали два таких класса и проверили, | ||
| + | |||
| + | Я не случайно разбил общую логику на два абстрактных класса. Теперь давайте ещё немного усложним пример. Позволим создавать несколько одиночек для каждого класса, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Интерфейс сложного пула одиночек | ||
| + | */ | ||
| + | abstract class RegistryFactory extends FactoryAbstract | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает экземпляр класса, | ||
| + | * | ||
| + | * @param integer|string $id - уникальный идентификатор одиночки | ||
| + | * @return static | ||
| + | */ | ||
| + | final public static function getInstance($id) | ||
| + | { | ||
| + | $className = static:: | ||
| + | if (isset(self:: | ||
| + | if (!(self:: | ||
| + | self:: | ||
| + | } | ||
| + | } else { | ||
| + | self:: | ||
| + | $id => new $className($id), | ||
| + | ]; | ||
| + | } | ||
| + | return self:: | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Удаляет экземпляр класса, | ||
| + | * | ||
| + | * @param integer|string $id - уникальный идентификатор одиночки. Если не указан, | ||
| + | * @return void | ||
| + | */ | ||
| + | final public static function removeInstance($id = null) | ||
| + | { | ||
| + | $className = static:: | ||
| + | if (isset(self:: | ||
| + | if (is_null($id)) { | ||
| + | unset(self:: | ||
| + | } else { | ||
| + | if (isset(self:: | ||
| + | unset(self:: | ||
| + | } | ||
| + | if (empty(self:: | ||
| + | unset(self:: | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | protected function __construct($id) | ||
| + | { | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | /** | ||
| + | * Первый пул одиночек | ||
| + | */ | ||
| + | class FirstFactory extends RegistryFactory | ||
| + | { | ||
| + | public $a = []; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Второй пул одиночек | ||
| + | */ | ||
| + | class SecondFactory extends FirstFactory | ||
| + | { | ||
| + | } | ||
| + | |||
| + | // Заполняем свойства одиночек | ||
| + | FirstFactory:: | ||
| + | FirstFactory:: | ||
| + | SecondFactory:: | ||
| + | SecondFactory:: | ||
| + | FirstFactory:: | ||
| + | FirstFactory:: | ||
| + | SecondFactory:: | ||
| + | SecondFactory:: | ||
| + | |||
| + | print_r(FirstFactory:: | ||
| + | // array(1, 5) | ||
| + | print_r(FirstFactory:: | ||
| + | // array(2, 6) | ||
| + | print_r(SecondFactory:: | ||
| + | // array(3, 7) | ||
| + | print_r(SecondFactory:: | ||
| + | // array(4, 8) | ||
| + | </ | ||
| + | |||
| + | Примерно по такому принципу работают некоторые ORM, позволяя хранить уже загруженные и инициализированные модели. | ||
| + | |||
| + | А теперь, | ||
| + | |||
| + | ===== Фабричный метод (Factory method) ===== | ||
| + | |||
| + | |||
| + | А теперь предлагаю немного понизить градус и снова вернуться к истокам. Допустим, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Фабрика | ||
| + | */ | ||
| + | interface Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Продукт | ||
| + | */ | ||
| + | interface Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Первая фабрика | ||
| + | */ | ||
| + | class FirstFactory implements Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return new FirstProduct(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Вторая фабрика | ||
| + | */ | ||
| + | class SecondFactory implements Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return new SecondProduct(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Первый продукт | ||
| + | */ | ||
| + | class FirstProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return 'The first product'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Второй продукт | ||
| + | */ | ||
| + | class SecondProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return ' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $factory = new FirstFactory(); | ||
| + | $firstProduct = $factory-> | ||
| + | $factory = new SecondFactory(); | ||
| + | $secondProduct = $factory-> | ||
| + | |||
| + | print_r($firstProduct-> | ||
| + | // The first product | ||
| + | print_r($secondProduct-> | ||
| + | // Second product | ||
| + | </ | ||
| + | |||
| + | В данном примере метод getProduct() является фабричным. | ||
| + | |||
| + | ===== Абстрактная фабрика (Abstract Factory) ===== | ||
| + | |||
| + | Бывает ситуация, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Какой-нибудь файл конфигурации | ||
| + | */ | ||
| + | class Config | ||
| + | { | ||
| + | public static $factory = 1; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Какой-то продукт | ||
| + | */ | ||
| + | interface Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Абстрактная фабрика | ||
| + | */ | ||
| + | abstract class AbstractFactory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает фабрику | ||
| + | * | ||
| + | * @return AbstractFactory - дочерний объект | ||
| + | * @throws Exception | ||
| + | */ | ||
| + | public static function getFactory() | ||
| + | { | ||
| + | switch (Config:: | ||
| + | case 1: | ||
| + | return new FirstFactory(); | ||
| + | case 2: | ||
| + | return new SecondFactory(); | ||
| + | } | ||
| + | throw new Exception(' | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | abstract public function getProduct(); | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | class FirstFactory extends AbstractFactory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return new FirstProduct(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Продукт первой фабрики | ||
| + | */ | ||
| + | class FirstProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return 'The product from the first factory'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | class SecondFactory extends AbstractFactory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return new SecondProduct(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Продукт второй фабрики | ||
| + | */ | ||
| + | class SecondProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return 'The product from second factory'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $firstProduct = AbstractFactory:: | ||
| + | Config:: | ||
| + | $secondProduct = AbstractFactory:: | ||
| + | |||
| + | print_r($firstProduct-> | ||
| + | // The first product from the first factory | ||
| + | print_r($secondProduct-> | ||
| + | // Second product from second factory | ||
| + | |||
| + | </ | ||
| + | |||
| + | Как видно из примера, | ||
| + | |||
| + | ===== Отложенная инициализация (Lazy Initialization) ===== | ||
| + | |||
| + | А вот вам ещё одна интересная ситуация. Представьте, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Какой-то продукт | ||
| + | */ | ||
| + | interface Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName(); | ||
| + | } | ||
| + | |||
| + | class Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var Product | ||
| + | */ | ||
| + | protected $firstProduct; | ||
| + | |||
| + | /** | ||
| + | * @var Product | ||
| + | */ | ||
| + | protected $secondProduct; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getFirstProduct() | ||
| + | { | ||
| + | |||
| + | if (!$this-> | ||
| + | $this-> | ||
| + | } | ||
| + | return $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Возвращает продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getSecondProduct() | ||
| + | { | ||
| + | |||
| + | if (!$this-> | ||
| + | $this-> | ||
| + | } | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Первый продукт | ||
| + | */ | ||
| + | class FirstProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return 'The first product'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Второй продукт | ||
| + | */ | ||
| + | class SecondProduct implements Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Возвращает название продукта | ||
| + | * | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() | ||
| + | { | ||
| + | return ' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $factory = new Factory(); | ||
| + | |||
| + | print_r($factory-> | ||
| + | // The first product | ||
| + | print_r($factory-> | ||
| + | // Second product | ||
| + | print_r($factory-> | ||
| + | // The first product | ||
| + | </ | ||
| + | |||
| + | При первом вызове метода, | ||
| + | |||
| + | ===== Прототип (Prototype) ===== | ||
| + | |||
| + | |||
| + | Некоторые объекты приходится создавать многократно. Есть смысл сэкономить на их инициализации, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Какой-то продукт | ||
| + | */ | ||
| + | interface Product | ||
| + | { | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Какая-то фабрика | ||
| + | */ | ||
| + | class Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var Product | ||
| + | */ | ||
| + | private $product; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * @param Product $product | ||
| + | */ | ||
| + | public function __construct(Product $product) | ||
| + | { | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Возвращает новый продукт путём клонирования | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return clone $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Продукт | ||
| + | */ | ||
| + | class SomeProduct implements Product | ||
| + | { | ||
| + | public $name; | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $prototypeFactory = new Factory(new SomeProduct()); | ||
| + | |||
| + | $firstProduct = $prototypeFactory-> | ||
| + | $firstProduct-> | ||
| + | |||
| + | $secondProduct = $prototypeFactory-> | ||
| + | $secondProduct-> | ||
| + | |||
| + | print_r($firstProduct-> | ||
| + | // The first product | ||
| + | print_r($secondProduct-> | ||
| + | // Second product | ||
| + | </ | ||
| + | |||
| + | Как видно из примера мы создали два никак не связанных объекта. | ||
| + | |||
| + | Строитель (Builder) | ||
| + | |||
| + | Ну и последний на сегодня шаблон – строитель. Он полезен, | ||
| + | |||
| + | < | ||
| + | <?php | ||
| + | /** | ||
| + | * Какой-то продукт | ||
| + | */ | ||
| + | class Product | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var string | ||
| + | */ | ||
| + | private $name; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * @param string $name | ||
| + | */ | ||
| + | public function setName($name) { | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * @return string | ||
| + | */ | ||
| + | public function getName() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Какая-то фабрика | ||
| + | */ | ||
| + | class Factory | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var Builder | ||
| + | */ | ||
| + | private $builder; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * @param Builder $builder | ||
| + | */ | ||
| + | public function __construct(Builder $builder) | ||
| + | { | ||
| + | $this-> | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Возвращает созданный продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | public function getProduct() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Какой-то строитель | ||
| + | */ | ||
| + | abstract class Builder | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * @var Product | ||
| + | */ | ||
| + | protected $product; | ||
| + | |||
| + | |||
| + | /** | ||
| + | * Возвращает созданный продукт | ||
| + | * | ||
| + | * @return Product | ||
| + | */ | ||
| + | final public function getProduct() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Создаёт продукт | ||
| + | * | ||
| + | * @return void | ||
| + | */ | ||
| + | public function buildProduct() | ||
| + | { | ||
| + | $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Первый строитель | ||
| + | */ | ||
| + | class FirstBuilder extends Builder | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Создаёт продукт | ||
| + | * | ||
| + | * @return void | ||
| + | */ | ||
| + | public function buildProduct() | ||
| + | { | ||
| + | parent:: | ||
| + | $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Второй строитель | ||
| + | */ | ||
| + | class SecondBuilder extends Builder | ||
| + | { | ||
| + | |||
| + | /** | ||
| + | * Создаёт продукт | ||
| + | * | ||
| + | * @return void | ||
| + | */ | ||
| + | public function buildProduct() | ||
| + | { | ||
| + | parent:: | ||
| + | $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | * ===================================== | ||
| + | | ||
| + | * ===================================== | ||
| + | */ | ||
| + | |||
| + | $firstDirector = new Factory(new FirstBuilder()); | ||
| + | $secondDirector = new Factory(new SecondBuilder()); | ||
| + | |||
| + | print_r($firstDirector-> | ||
| + | // The product of the first builder | ||
| + | print_r($secondDirector-> | ||
| + | // The product of second builder | ||
| + | </ | ||
| + | |||
| + | Итак, мы рассмотрели 9 шаблонов проектирования. Это довольно длинная статья. Поэтому хотелось бы узнать ваше мнение. Есть ли смысл в проделанной работе и стоит ли мне завершить цикл, рассказав о структурных шаблонах и шаблонах поведения? | ||
| + | |||
| + | Весь опубликованный код можно найти и на [[https:// | ||
php_patterns.1625636561.txt.gz · Last modified: 2023/09/14 06:06 (external edit)