Better Laravel Monoliths: Observer Pattern

Manish Sharma
3 min readAug 19, 2023

--

Observer Pattern in Laravel

This is Part-2 . Please read Part-1 for better understanding.

Consider this problem:

“If the delivery address for an order is changed within allowed time limits, send a notification to the Logistics API provider. Also send an email and an SMS to that customer notifying them of their decision”

In this case

Subject is Ecommerce order.

Event is an address change.

Actions to be taken are : Notifying connected Logistics provider, Sending an email and Sending an SMS. In other words we have three Listeners that are interested in “AddressChange” event. This is a perfect case of Observer Pattern.

What is the Observer Pattern ?

Ii is a behavioural design pattern that defines a one to many relationship between subject and observers in a loosely coupled manner by sending event notification to registered observers of change in state of Subject.

Observer Pattern in Laravel
Observer Pattern in Laravel

This provides a good extent of loose coupling (except for registration of observers). If you want a maintainable loosely coupled solution to this problem, Observer pattern is an ideal choice for monoliths and Pub Sub for microservices.

What problem does Observable pattern solve ?

  1. Allowing multiple observers to be notified when the subject changes its state. This allows any number of dependent objects to be updated immediately.

2. Providing loose coupling between Subject and Observers.

3. Promoting asynchronous reaction of events within the system by enabling parallel processing (through Jobs and Queues for example).

How is the Observer Pattern different from Pub-Sub Pattern ?

Pub-Sub promoted further loose coupling using Event Bus or Broker. In this mechanism “Subject” and “Observers” may act in an independent manner. In most practical situations the observer pattern is better for monoliths and pub-sub for microservices.

But How can I Implement this in Laravel ?

What we are implementing is given in diagram below:

Observer Pattern implementation in Laravel
Observer Pattern implementation in Laravel

To start with, The updateAddress() action of AddressController validates input using AddressChangeRequest and converts it into AddressChangeDTO object.(remember Adapter pattern works as a bridge between two incompatible interfaces, We should never pass HTTP request instances to Service class, for requests may originate from Terminal or other Non-HTTP clients as well). It passes AddressChangeDTO object to OrderService.

OrderService uses OrderRepository to update the address and passes the order object to AddressChangeNotifService.

Order Service

AddressChangeNotifService raises AddressChangeEvent event (Observer pattern) using Order as subject. We have registered 3 event-listeners in App\Services\EventServiceProvider(Remember in Observer pattern, System should “know” about this coupling)

protected $listen = [
AddressChangeEvent::class => [
AddressChangeListenerForLogistics::class,
AddressChangeListenerForEmail::class,
AddressChangeListenerForSMS::class,
]
];

The event is:

These listeners are supposed to use Laravel Queue to perform their duties. In our example We are just logging it. You can view the output in storage/logs/laravel.log .

Consider this Listener:

The handle() method of listener class performs the actual work. It hold Event object as argument: handle(AddressChangeEvent $event).

In real world Listeners should delegate time consuming blocking tasks to Queues.

That’s all.

Feel free to comment if you have any doubt or query.

You may download source doe from this repository.

Happy Coding.

--

--