---
title: "Abstract Factory - сімейства об'єктів"
url: https://laravelukraine.com/blog/abstract-factory-simeistva-objektiv
date: 2026-06-01
---

# Abstract Factory - сімейства об'єктів

Abstract Factory створює сім'ї пов'язаних об'єктів без прив'язки до конкретних класів. Клієнт працює з набором інтерфейсів і не знає, яка саме реалізація стоїть за ними.

### Яку проблему вирішує

Інколи об'єкти мають бути узгоджені між собою, а не просто взаємозамінні поодинці. Наприклад, пошта і нотифікації одного хмарного провайдера: не можна випадково змішати поштовий клієнт від AWS і нотифікатор від іншого сервісу. Якщо створювати їх розкидано через `new`, нічого не гарантує, що вся група належить одному провайдеру.

### Як вирішує

Один інтерфейс-фабрика оголошує методи створення для кожного члена сім'ї. Конкретна фабрика повертає узгоджений набір реалізацій. Щоб замінити всю сім'ю одразу, достатньо підставити іншу фабрику - решта коду не змінюється.

```php
interface Mailer
{
  public function send(string $to, string $body): void;
}

interface Notifier
{
  public function notify(string $userId, string $message): void;
}

interface ServicesFactory
{
  public function mailer(): Mailer;
  public function notifier(): Notifier;
}
```

Конкретна фабрика збирає сім'ю одного провайдера:

```php
class SesMailer implements Mailer
{
  public function send(string $to, string $body): void
  {
    // SES send
  }
}

class SesNotifier implements Notifier
{
  public function notify(string $userId, string $message): void
  {
    // SES notify
  }
}

class SesFactory implements ServicesFactory
{
  public function mailer(): Mailer
  {
    return new SesMailer();
  }

  public function notifier(): Notifier
  {
    return new SesNotifier();
  }
}
```

Клієнт залежить лише від фабрики й інтерфейсів, не знаючи про SES:

```php
class NotificationService
{
  public function __construct(private ServicesFactory $factory) {}

  public function run(): void
  {
    $this->factory->mailer()->send('a@b.com', 'Hello');
    $this->factory->notifier()->notify('user1', 'Hi');
  }
}
```

### Де застосовувати

- Кілька провайдерів чи конфігурацій, члени яких мусять бути сумісні між собою (хмарні сервіси, теми оформлення, набори драйверів).
- У Laravel роль абстрактної фабрики часто виконує сервіс-контейнер разом із менеджерами драйверів (`Cache`, `Queue`, `Mail`): метод `driver()` повертає узгоджену реалізацію за конфігом.

### Плюси та мінуси

- **+** Гарантує сумісність об'єктів усередині однієї сім'ї.
- **+** Ізолює клієнта від конкретних класів - заміна провайдера в одному місці.
- **−** Додає шар абстракції та класів; новий член сім'ї потребує правок усіх фабрик.
- **−** Надлишковий, якщо треба замінювати лише один об'єкт, а не цілу сім'ю - тоді достатньо Factory Method або звичайного зв'язування в контейнері.
