Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке патерн Observer і як він реалізований у Laravel?

Observer (Спостерігач) - об'єкт-«видавець» повідомляє про зміну стану всіх зацікавлених «підписників», не знаючи про них нічого конкретного. Підписники реєструються самі.

Проблема, яку він розв'язує:

public function pay(Order $order): void
{
    $order->markAsPaid();
    $this->mailer->sendReceipt($order);
    $this->warehouse->reserve($order);
    $this->analytics->trackPurchase($order);
    $this->crm->updateCustomer($order->customer);
    // кожна нова реакція - правка цього методу
}

Оплата «знає» про пошту, склад, аналітику й CRM. Зміни в будь-якій з цих систем зачіпають код оплати.

З Observer (у Laravel - події й слухачі):

public function pay(Order $order): void
{
    $order->markAsPaid();
    OrderPaid::dispatch($order);
}
class SendReceipt { public function handle(OrderPaid $event): void { /* ... */ } }
class ReserveStock { public function handle(OrderPaid $event): void { /* ... */ } }

Laravel знаходить слухачів автоматично за типом події в методі handle. Нова реакція - новий клас-слухач, код оплати не змінюється.

Інші реалізації Observer у Laravel:

  • спостерігачі моделей (#[ObservedBy(OrderObserver::class)]) - реакція на created, updated, deleted;
  • події моделей (static::created(...));
  • трансляція подій у браузер (ShouldBroadcast) - підписники навіть в іншому процесі;
  • Livewire #[On] і події JavaScript - та сама ідея на клієнті.

Переваги: слабка зв'язність, легко додавати реакції, слухачі можна виконувати в черзі (ShouldQueue).

Недоліки й пастки:

  • неявний потік: з коду OrderPaid::dispatch() не видно, що станеться далі - треба шукати слухачів (php artisan event:list);
  • порядок виконання слухачів не варто вважати гарантованим для бізнес-логіки;
  • спостерігачі моделей спрацьовують на кожне збереження, включно з сидерами, імпортом, тестами - і не спрацьовують на масові запити (Order::where(...)->update());
  • транзакції: подія, оброблена до коміту, може відправити лист про замовлення, яке потім відкотиться - ShouldDispatchAfterCommit чи afterCommit для слухачів у черзі.

Коли не варто: якщо дія - обов'язкова частина сценарію (без неї операція неуспішна), її краще викликати явно, а не ховати в слухачі.

Докладніше в документації: Refactoring.Guru: Observer

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання