Назад к вопросам
Middle
104
questionbank
Какую проблему решают фабричные методы и фабрика в программировании?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Фабричные методы и фабрика решают проблему создания объектов без указания конкретного класса, который будет инстанцирован. Они предоставляют интерфейс для создания объектов в родительском классе, позволяя подклассам изменять тип создаваемых объектов.
Преимущества использования:
- Ослабление связанности: Код, использующий фабрику, не зависит от конкретных классов, что облегчает внесение изменений и расширение системы.
- Упрощение добавления новых типов объектов: Для добавления нового типа объекта достаточно создать новый класс, реализующий общий интерфейс, и расширить фабрику.
- Централизация создания объектов: Логика создания объектов сосредоточена в одном месте, что делает код более понятным и поддерживаемым.
Пример c фабричным методом:
<?php
// Интерфейс продукта
interface Product {
public function operation(): string;
}
// Конкретные продукты
class ConcreteProductA implements Product {
public function operation(): string {
return "Результат работы ConcreteProductA";
}
}
class ConcreteProductB implements Product {
public function operation(): string {
return "Результат работы ConcreteProductB";
}
}
// Абстрактный класс создателя
abstract class Creator {
abstract public function factoryMethod(): Product;
public function someOperation(): string {
// Вызываем фабричный метод для создания объекта продукта
$product = $this->factoryMethod();
// Используем продукт
return "Creator: Та же логика работает с " . $product->operation();
}
}
// Конкретные создатели
class ConcreteCreatorA extends Creator {
public function factoryMethod(): Product {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
public function factoryMethod(): Product {
return new ConcreteProductB();
}
}
// Использование
function clientCode(Creator $creator) {
echo "Клиент: Я не знаю, с каким создателем работаю, но это все равно сработает.\n" . $creator->someOperation() . "\n\n";
}
echo "Пример с ConcreteCreatorA:\n";
clientCode(new ConcreteCreatorA());
echo "Пример с ConcreteCreatorB:\n";
clientCode(new ConcreteCreatorB());
?>
Пример c абстрактной фабрикой:
<?php
// Интерфейсы семейства продуктов
interface AbstractProductA {
public function usefulFunctionA(): string;
}
interface AbstractProductB {
public function usefulFunctionB(): string;
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string;
}
// Конкретные продукты для первой фабрики
class ConcreteProductA1 implements AbstractProductA {
public function usefulFunctionA(): string {
return "Результат работы ProductA1.";
}
}
class ConcreteProductA2 implements AbstractProductA {
public function usefulFunctionA(): string {
return "Результат работы ProductA2.";
}
}
class ConcreteProductB1 implements AbstractProductB {
public function usefulFunctionB(): string {
return "Результат работы ProductB1.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string {
$result = $collaborator->usefulFunctionA();
return "Результат работы ProductB1, взаимодействующий с ({$result})";
}
}
class ConcreteProductB2 implements AbstractProductB {
public function usefulFunctionB(): string {
return "Результат работы ProductB2.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string {
$result = $collaborator->usefulFunctionA();
return "Результат работы ProductB2, взаимодействующий с ({$result})";
}
}
// Интерфейс абстрактной фабрики
interface AbstractFactory {
public function createProductA(): AbstractProductA;
public function createProductB(): AbstractProductB;
}
// Конкретные фабрики
class ConcreteFactory1 implements AbstractFactory {
public function createProductA(): AbstractProductA {
return new ConcreteProductA1();
}
public function createProductB(): AbstractProductB {
return new ConcreteProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory {
public function createProductA(): AbstractProductA {
return new ConcreteProductA2();
}
public function createProductB(): AbstractProductB {
return new ConcreteProductB2();
}
}
// Использование
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Клиент: Тестирование со вторым типом фабрики:\n";
clientCode(new ConcreteFactory2());
?>