Назад к вопросам
Middle
102
questionbank
Расскажите о паттерне проектирования 'фабрика' и его применении в PHP.
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Фабрика (Factory Method и Abstract Factory) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания объектов в суперклассе, но позволяет подклассам изменять тип создаваемых объектов.
Применение в PHP:
- Изоляция процесса создания объектов: Позволяет отделить код, создающий объекты, от кода, использующего эти объекты. Это упрощает изменение типа создаваемых объектов без изменения клиентского кода.
- Создание объектов на основе конфигурации или условий: Можно использовать фабрику для создания различных реализаций одного интерфейса в зависимости от параметров, переданных в фабрику, или настроек приложения.
- Упрощение тестирования: Заменяя реальные объекты моками или заглушками в фабрике при тестировании, можно легко контролировать зависимости.
Factory Method: Определяет метод создания объекта, который должен быть реализован в подклассах.
<?php
// Интерфейс продукта
interface Product {
public function operation(): string;
}
// Конкретный продукт A
class ConcreateProductA implements Product {
public function operation(): string {
return "Результат операции продукта A";
}
}
// Конкретный продукт B
class ConcreateProductB implements Product {
public function operation(): string {
return "Результат операции продукта B";
}
}
// Интерфейс создателя
abstract class Creator {
abstract public function factoryMethod(): Product;
public function someOperation(): string {
// Вызов фабричного метода для создания объекта
$product = $this->factoryMethod();
// Использование объекта
$result = "Создатель: Работаю с " . $product->operation();
return $result;
}
}
// Конкретный создатель A
class ConcreateCreatorA extends Creator {
public function factoryMethod(): Product {
return new ConcreateProductA();
}
}
// Конкретный создатель B
class ConcreateCreatorB extends Creator {
public function factoryMethod(): Product {
return new ConcreateProductB();
}
}
// Использование
// $creatorA = new ConcreateCreatorA();
// echo $creatorA->someOperation();
// $creatorB = new ConcreateCreatorB();
// echo $creatorB->someOperation();
Abstract Factory: Предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
<?php
// Интерфейс абстрактной фабрики
interface AbstractFactory {
public function createProductA(): AbstractProductA;
public function createProductB(): AbstractProductB;
}
// Интерфейс абстрактного продукта A
interface AbstractProductA {
public function usefulFunctionA(): string;
}
// Интерфейс абстрактного продукта B
interface AbstractProductB {
public function usefulFunctionB(): string;
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string;
}
// Конкретная фабрика 1
class ConcreteFactory1 implements AbstractFactory {
public function createProductA(): AbstractProductA {
return new ConcreteProductA1();
}
public function createProductB(): AbstractProductB {
return new ConcreteProductB1();
}
}
// Конкретная фабрика 2
class ConcreteFactory2 implements AbstractFactory {
public function createProductA(): AbstractProductA {
return new ConcreteProductA2();
}
public function createProductB(): AbstractProductB {
return new ConcreteProductB2();
}
}
// Конкретный продукт A1
class ConcreteProductA1 implements AbstractProductA {
public function usefulFunctionA(): string {
return "Результат продукта A1.";
}
}
// Конкретный продукт A2
class ConcreteProductA2 implements AbstractProductA {
public function usefulFunctionA(): string {
return "Результат продукта A2.";
}
}
// Конкретный продукт B1
class ConcreteProductB1 implements AbstractProductB {
public function usefulFunctionB(): string {
return "Результат продукта B1.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string {
$result = $collaborator->usefulFunctionA();
return "Результат продукта B1, работающего с (" . $result . ")";
}
}
// Конкретный продукт B2
class ConcreteProductB2 implements AbstractProductB {
public function usefulFunctionB(): string {
return "Результат продукта B2.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string {
$result = $collaborator->usefulFunctionA();
return "Результат продукта B2, работающего с (" . $result . ")";
}
}
// Использование
// function clientCode(AbstractFactory $factory) {
// $productA = $factory->createProductA();
// $productB = $factory->createProductB();
// echo $productB->usefulFunctionB() . "\n";
// echo $productB->anotherUsefulFunctionB($productA) . "\n";
// }
//
// echo "Клиент: Тестирование с первым типом фабрики:\n";
// clientCode(new ConcreteFactory1());
//
// echo "Клиент: Тестирование со вторым типом фабрики:\n";
// clientCode(new ConcreteFactory2());