Доменна подія - факт, що вже стався в предметній області і важливий для бізнесу: OrderPlaced, PaymentReceived, SubscriptionCancelled. Назва - дієслово в минулому часі, бо подію не можна «скасувати» - лише відреагувати на неї.
final class OrderPlaced
{
public function __construct(
public readonly int $orderId,
public readonly int $customerId,
public readonly int $totalAmount,
public readonly CarbonImmutable $placedAt,
) {}
}
Навіщо вони:
1. Розв'язати зв'язки між частинами системи. Оформлення замовлення не повинно знати про лист клієнту, нарахування бонусів, оновлення аналітики й сповіщення складу:
// без подій: оформлення знає про все
$order->save();
$mailer->sendConfirmation($order);
$loyalty->addPoints($order);
$warehouse->reserve($order);
// з подією: оформлення лише повідомляє факт
OrderPlaced::dispatch($order->id, ...);
// окремі слухачі: лист, бонуси, склад - кожен незалежно
Новий обробник (наприклад, вебхук партнеру) додається без зміни коду оформлення.
2. Явно назвати важливі моменти бізнес-процесу - події стають частиною єдиної мови.
3. Інтеграція між контекстами чи сервісами - подія передається в чергу чи брокер повідомлень.
4. Журнал і аудит - історія того, що відбувалося.
У Laravel - події й слухачі:
class SendOrderConfirmation implements ShouldQueue
{
public function handle(OrderPlaced $event): void { /* ... */ }
}
Що варто знати:
- подія - про факт, а не команда:
OrderPlaced, а неSendOrderEmail; - подія після коміту транзакції: якщо слухач у черзі отримає подію до коміту, він не знайде замовлення в базі. У Laravel - інтерфейс
ShouldDispatchAfterCommitдля подій чиafterCommitдля слухачів; - дані в події - ідентифікатори й значущі значення, а не ціла модель, що може змінитися до обробки;
- приховані залежності: коли подій і слухачів багато, важко зрозуміти, що відбувається після дії.
php artisan event:listі чіткі назви допомагають.