Ответ
Шина событий (Event Bus) — это архитектурный паттерн, реализующий механизм публикации/подписки (Pub/Sub). Он обеспечивает слабосвязанное взаимодействие между компонентами системы: отправители событий (публикаторы) и их получатели (подписчики) не знают друг о друге, общаясь только через общую шину.
Основные компоненты:
- Событие (Event): Объект-сообщение, содержащее данные о произошедшем действии.
- Публикатор (Publisher): Компонент, который создает и отправляет событие в шину.
- Подписчик (Subscriber/Listener): Компонент, который регистрируется в шине для обработки событий определенного типа.
- Шина (Bus): Центральный диспетчер, который принимает события от публикаторов и доставляет их всем соответствующим подписчикам.
Реализация простой шины на PHP:
class Event {
public function __construct(public readonly string $name, public readonly array $payload = []) {}
}
class EventBus {
private array $subscribers = [];
public function subscribe(string $eventClass, callable $handler): void {
$this->subscribers[$eventClass][] = $handler;
}
public function publish(Event $event): void {
$eventClass = get_class($event);
foreach ($this->subscribers[$eventClass] ?? [] as $handler) {
$handler($event);
}
}
}
// Определение событий
class UserRegisteredEvent extends Event {}
class OrderShippedEvent extends Event {}
// Использование
$bus = new EventBus();
// Подписка на событие
$bus->subscribe(UserRegisteredEvent::class, function (UserRegisteredEvent $event) {
echo "Отправляем welcome-email пользователю: " . $event->payload['email'];
});
$bus->subscribe(UserRegisteredEvent::class, function (UserRegisteredEvent $event) {
echo "Создаем начальный профиль для ID: " . $event->payload['userId'];
});
// Публикация события
$bus->publish(new UserRegisteredEvent('user.registered', [
'userId' => 456,
'email' => 'user@example.com'
]));
Преимущества:
- Слабая связанность: Компоненты системы независимы, их легко менять и тестировать.
- Расширяемость: Новую реакцию на событие можно добавить, просто создав нового подписчика, не меняя код публикатора.
- Асинхронность: Шину можно адаптировать для асинхронной обработки событий через очереди (например, RabbitMQ, Kafka), что повышает отзывчивость системы.
Недостатки:
- Сложность отладки: Поток выполнения становится нелинейным, что усложняет трассировку.
- Управление ошибками: Необходима стратегия обработки сбоев в подписчиках, чтобы один упавший обработчик не ломал всю цепочку.
В экосистеме PHP паттерн широко используется в рамках Symfony с его компонентом EventDispatcher и в Laravel Events.