3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace RefactoringGuru\FactoryMethod\Conceptual; /** * Паттерн Фабричный Метод * * Назначение: Определяет общий интерфейс для создания объектов в суперклассе, * позволяя подклассам изменять тип создаваемых объектов. */ /** * Класс Создатель объявляет фабричный метод, который должен возвращать объект * класса Продукт. Подклассы Создателя обычно предоставляют реализацию этого * метода. */ abstract class Creator { /** * Обратите внимание, что Создатель может также обеспечить реализацию * фабричного метода по умолчанию. */ abstract public function factoryMethod(): Product; /** * Также заметьте, что, несмотря на название, основная обязанность Создателя * не заключается в создании продуктов. Обычно он содержит некоторую базовую * бизнес-логику, которая основана на объектах Продуктов, возвращаемых * фабричным методом. Подклассы могут косвенно изменять эту бизнес-логику, * переопределяя фабричный метод и возвращая из него другой тип продукта. */ public function someOperation(): string { // Вызываем фабричный метод, чтобы получить объект-продукт. $product = $this->factoryMethod(); // Далее, работаем с этим продуктом. $result = "Creator: creator's code has just worked with " . $product->operation(); return $result; } } /** * Конкретные Создатели переопределяют фабричный метод для того, чтобы изменить * тип результирующего продукта. */ class ConcreteCreator1 extends Creator { /** * Обратите внимание, что сигнатура метода по-прежнему использует тип * абстрактного продукта, хотя фактически из метода возвращается конкретный * продукт. Таким образом, Создатель может оставаться независимым от * конкретных классов продуктов. */ public function factoryMethod(): Product { return new ConcreteProduct1(); } } class ConcreteCreator2 extends Creator { public function factoryMethod(): Product { return new ConcreteProduct2(); } } /** * Интерфейс Продукта объявляет операции, которые должны выполнять все * конкретные продукты. */ interface Product { public function operation(): string; } /** * Конкретные Продукты предоставляют различные реализации интерфейса Продукта. */ class ConcreteProduct1 implements Product { public function operation(): string { return "{Result of the ConcreteProduct1}"; } } class ConcreteProduct2 implements Product { public function operation(): string { return "{Result of the ConcreteProduct2}"; } } /** * Клиентский код работает с экземпляром конкретного создателя, хотя и через его * базовый интерфейс. Пока клиент продолжает работать с создателем через базовый * интерфейс, вы можете передать ему любой подкласс создателя. */ function clientCode(Creator $creator) { // ... echo "Client: I'm not aware of the creator's class, but it still works.\n" . $creator->someOperation(); // ... } /** * Приложение выбирает тип создателя в зависимости от конфигурации или среды. */ echo "App: Launched with the ConcreteCreator1.\n"; clientCode(new ConcreteCreator1()); echo "\n\n"; echo "App: Launched with the ConcreteCreator2.\n"; clientCode(new ConcreteCreator2());
Output for 7.3.0 - 7.3.31, 7.4.0 - 7.4.25, 8.0.0 - 8.0.12, 8.1rc1 - rc3
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: creator's code has just worked with {Result of the ConcreteProduct1} App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: creator's code has just worked with {Result of the ConcreteProduct2}

preferences:
41.03 ms | 461 KiB | 5 Q