Фабрика (Fabric) паттерн
Паттерн «Фабрика» (Factory)
📌 Что это такое?
Factory — это порождающий паттерн проектирования, цель которого — инкапсулировать логику создания объектов. То есть, вместо того чтобы напрямую писать new Class(), мы обращаемся к фабричному методу, который решает, какой объект и как создать.
Это особенно полезно, если:
-
ты не хочешь, чтобы код знал, какой именно класс создаётся;
-
тебе нужно создавать разные реализации одного интерфейса;
-
в процессе создания объекта нужна сложная логика.
Пример из реальной жизни
Допустим, ты делаешь сервис оплаты. У тебя есть несколько платёжных провайдеров: Stripe, PayPal, Tinkoff.
Ты можешь создать интерфейс PaymentGatewayInterface и конкретные реализации:
interface PaymentGatewayInterface {
public function pay(float $amount): bool;
}
class StripeGateway implements PaymentGatewayInterface {
public function pay(float $amount): bool {
// логика Stripe
return true;
}
}
class PayPalGateway implements PaymentGatewayInterface {
public function pay(float $amount): bool {
// логика PayPal
return true;
}
}
Пример: Реализация Factory в Laravel-стиле:
class PaymentGatewayFactory
{
public static function make(string $driver): PaymentGatewayInterface
{
return match ($driver) {
'stripe' => new StripeGateway(),
'paypal' => new PayPalGateway(),
default => throw new InvalidArgumentException("Unsupported gateway: $driver"),
};
}
}
Использование:
$gateway = PaymentGatewayFactory::make('stripe');
$gateway->pay(1000);
Laravel-специфика
В Laravel ты часто можешь обернуть фабрику в сервис-провайдер, зарегистрировать её в контейнере, или использовать через Service Container:
app()->bind(PaymentGatewayInterface::class, function () {
$driver = config('payment.driver'); // допустим, 'stripe'
return PaymentGatewayFactory::make($driver);
});
// И потом в контроллере:
public function pay(PaymentGatewayInterface $gateway)
{
$gateway->pay(1000);
}
Применение в Laravel:
-
Model Factories —
factory(User::class)->create()— это тоже паттерн Фабрика! -
Сервисные обёртки — создание сервисов в зависимости от типа пользователя, роли, страны и т.д.
-
Queue Job Dispatchers, Notification Channels, Log Handlers — все они могут использовать фабричный подход.
Когда использовать
✅ Когда создание объекта зависит от условий (тип, конфигурация, пользовательская роль).
✅ Когда нужно разделить ответственность между логикой приложения и созданием объектов.
❌ Не использовать, если объект тривиален (new User() без условий и зависимостей).