Паттерн Фабрика в PHP
Короткий урок по реализации простого фабричного метода (Factory Method) на PHP.
Описание
В этом скринкасте мы создали три файла: Product.php, Factory.php и demo.php. Класс Factory инкапсулирует логику создания объектов Product, что позволяет избежать дублирования кода при инстанцировании и упрощает расширение системы.
UML-диаграмма
Заметка: лучше использовать интерфейс
В примере выше фабрика возвращает конкретный класс Product — это упрощённый вариант Simple Factory. В полноценном паттерне Factory Method фабрика возвращает ProductInterface, чтобы вызывающий код зависел от абстракции, а не от конкретного класса. Так реализацию легко подменять:
interface ProductInterface
{
public function getInfo(): string;
}
class Product implements ProductInterface
{
public function getInfo(): string
{
return $this->type . ': ' . $this->name;
}
}
class Factory
{
public static function create(string $type, string $name): ProductInterface
{
return new Product($type, $name);
}
}
Пример результата
После выполнения php demo.php в терминале появится:
Laptop: MacBook Pro
Преимущества
- Отделяет клиентский код от конкретных классов продуктов: клиент работает через интерфейс.
- Вся логика выбора класса собрана в одном месте — в фабрике.
- Добавление нового продукта не требует правок в клиентском коде (принцип открытости/закрытости).
- Создание легко подменить фейком в тестах.
Когда использовать
- Когда заранее неизвестно, объект какого класса нужно создать.
- Когда создание объекта требует нетривиальной логики или конфигурации.
- Когда решение о типе продукта должны принимать наследники фабрики.
- Когда нужно централизовать и переиспользовать создание объектов.
Использование в Laravel
В Laravel фабричный метод — это Illuminate\Database\Connectors\ConnectionFactory: по драйверу из конфигурации она решает, какой коннектор создать (MySqlConnector, PostgresConnector и другие). В прикладном коде тот же приём — фабрики моделей (Illuminate\Database\Eloquent\Factories\Factory): метод definition() описывает, как собрать модель, а Model::factory() прячет конкретику.