Observer is one of the most commonly used patterns in object-oriented programming, and in the Magento 2 ecosystem it is built into the core of the platform. If you have ever written an event observer in Magento, you have used this pattern – often without realising it.
The idea behind Observer
Observer defines a one-to-many relationship between objects: when one object changes state (Subject/Publisher), all objects that depend on it (Observers/Subscribers) are automatically notified. The Subject only knows their shared interface.
Classic PHP implementation
<?php
interface ObserverInterface
{
public function update(string $event, mixed $data): void;
}
class EventDispatcher
{
private array $observers = [];
public function attach(string $event, ObserverInterface $observer): void
{
$this->observers[$event][] = $observer;
}
public function notify(string $event, mixed $data = null): void
{
foreach ($this->observers[$event] ?? [] as $observer) {
$observer->update($event, $data);
}
}
}
// Usage
$dispatcher = new EventDispatcher();
$dispatcher->attach('order.placed', new EmailNotificationObserver());
$dispatcher->attach('order.placed', new AuditLogObserver());
$dispatcher->notify('order.placed', ['order_id' => 12345]);
Observer in Magento 2 – the event system
Register in events.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_place_after">
<observer name="vendor_module_order_placed"
instance="Vendor\Module\Observer\OrderPlacedObserver"/>
</event>
</config>
Implementation:
<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class OrderPlacedObserver implements ObserverInterface
{
public function __construct(private \Psr\Log\LoggerInterface $logger) {}
public function execute(Observer $observer): void
{
$order = $observer->getData('order');
$this->logger->info('New order placed', [
'order_id' => $order->getId(),
'grand_total' => $order->getGrandTotal(),
]);
}
}
Observer vs Plugin – when to use which?
| Criterion | Observer (Event) | Plugin |
|---|---|---|
| Integration point | Event defined by Magento | Any public method |
| Data modification | Limited (data from the event) | Full (arguments and return value) |
| Coupling to code | Loose | Tighter |
| Typical use | Reacting to business actions | Modifying method behaviour |
Practical rule: if Magento emits an event for your use case – use an Observer. If not – reach for a Plugin.
Summary
Observer promotes loose coupling between components. In Magento 2 this pattern is the foundation of the platform’s extensibility. Knowing the classic GoF implementation helps you better understand what happens “under the hood” when you register an event observer in XML.
