Exploring the Observer Pattern in Software Architecture: A Laravel Perspective

Photo by Jessica Lewis on Unsplash

Exploring the Observer Pattern in Software Architecture: A Laravel Perspective

Design Patterns Aug 20, 2023
💡
In the dynamic realm of software architecture, one design pattern emerges as a guiding star, illuminating the path to decoupling components and orchestrating seamless communication between objects. The Observer pattern, with its remarkable versatility, extends its influence from UI updates to intricate event-driven ecosystems. This article embarks on an illuminating journey through the intricacies, merits, and the practical realization of the Observer pattern using the robust event system provided by the Laravel framework.

Understanding the Observer Pattern:

At its heart, the Observer pattern establishes a remarkable symphony between objects - a one-to-many relationship that elegantly empowers a subject object to gracefully notify its dependent observer objects about changes in its state. This pattern's true prowess emerges when there's a need to propagate modifications in one object throughout others, all while preserving a gentle, loose coupling between them. The Observer pattern thrives in its ability to facilitate communication without ensnaring objects in intricate dependencies, a balance that lends itself to the art of maintaining object synchronization.

Real-Life Analogy: Newspaper Subscription:

Imagine the Observer pattern as a masterful conductor orchestrating a newspaper subscription service. Here, subscribers gracefully take on the role of observers, akin to individuals eagerly awaiting the morning paper. The newspaper publisher, standing as the subject, presents its latest creation. When a new edition unfurls, much like a change in state, the Observer pattern springs into action, promptly informing all subscribers and delivering their copies. This analogy mirrors the Observer pattern's innate charm in managing communication effortlessly.

Mechanics of the Observer Pattern:

Seated within the realm of behavioral design patterns, the Observer pattern thrives on a nuanced interplay of key components:

  1. Subject (Observable): This paramount entity upholds a register of its devoted observers. It wields methods to gracefully attach, detach, and broadcast notifications of state changes.
  2. Observers: These are the inquisitive souls, the dependent objects, eager to catch wind of the subject's evolving state. Observers eloquently declare their interest by registering themselves with the subject, ready to be awakened.
  3. Attach/Detach: In this harmonious ballet, observers attach themselves to the subject to partake in the symphony of state changes. When the need wanes, they gracefully detach, allowing the dance to continue.
  4. Notify: The heart of the matter lies in the subject's capacity to notify all attached observers when its state undergoes transformation. Observers respond by adjusting their demeanor in accordance with the new state, much like instruments fine-tuning their melody.

By advocating for loose coupling, the Observer pattern opens a realm of possibility where objects interact without the heaviness of direct dependencies. This emancipation empowers the system's evolution, allowing for the seamless introduction of new observers or subjects without ruffling the serenity of the existing codebase.

Implementation of Observer Pattern in Laravel:

Within the expanse of the Laravel framework, the Observer pattern finds not just a dwelling but a stage upon which its elegance can truly shine - the event system. The Observer pattern elegantly manifests through the following stages:

  1. Event Creation: With a touch of artisan magic, events come to life. A simple command, php artisan make:event EventName, conjures an event into existence.
  2. Listener Crafting: The artisans continue their craft, sculpting listeners with the command php artisan make:listener ListenerName --event=EventName. These listeners are the ears attuned to the symphony of events.
  3. Registration: The grand gathering of listeners commences in the EventServiceProvider class, where the threads of events and listeners are woven together, creating a tapestry of communication.
  4. Event Dispatch: A flourish of syntax, event(new EventName($data)), unfurls the event, sending forth ripples of notification, an act akin to launching a paper boat onto the tranquil waters of an event-driven world.

Scenario: New Blog Post Published:

In the fast-paced world of blogging, when a new blog post comes out, it's like weaving a web of connections. Think of it as a beautiful symphony where everyone gets the news together. Imagine using a special tool called the Observer pattern in the Laravel framework. It's like the conductor of this symphony, making sure that when a new blog post is ready, all the right people are notified in a smooth and efficient way.

So, the goal here is to smoothly fit this Observer pattern into Laravel. This way, whenever a new blog post is published, it's like the conductor waving their baton and the subscribers hear the music. It's a step-by-step process that aims to make sure users get a professional and seamless experience.

Step 1: Event Definition

Create an event named NewBlogPostPublished to encapsulate the information about the newly published blog post. Run the following command to generate the event:

php artisan make:event NewBlogPostPublished

Open the generated NewBlogPostPublished.php event file located in the app/Events directory. Modify it to include the necessary information:

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class NewBlogPostPublished
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $title;
    public $author;

    public function __construct($title, $author)
    {
        $this->title = $title;
        $this->author = $author;
    }
}

Step 2: Listener Ensemble

Create a listener named SendEmailNotification to handle the email notification when a new blog post is published. Run the following command to generate the listener:

php artisan make:listener SendEmailNotification --event=NewBlogPostPublished

Open the generated SendEmailNotification.php listener file located in the app/Listeners directory. Modify it to send email notifications to subscribers:

namespace App\Listeners;

use App\Events\NewBlogPostPublished;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class SendEmailNotification
{
    public function handle(NewBlogPostPublished $event)
    {
        // Code to send email notification to subscribers
        $subscribers = Subscribers::all(); // Replace with actual subscriber retrieval logic

        foreach ($subscribers as $subscriber) {
            $emailData = [
                'title' => $event->title,
                'author' => $event->author,
                'subscriber' => $subscriber->email,
            ];

            // Send email using Laravel's Mail facade
            Mail::to($subscriber->email)->send(new NewBlogPostNotificationMail($emailData));
        }
    }
}

Step 3: Event Eruption

Trigger the NewBlogPostPublished event when a new blog post is successfully published. In your blog post publication logic, add the following code:

use App\Events\NewBlogPostPublished;

// ... Publish the new blog post ...

// Trigger the NewBlogPostPublished event
event(new NewBlogPostPublished($newPost->title, $newPost->author));

Step 4: Listener's Aria

Create a mail notification named NewBlogPostNotificationMail to send the email notification to subscribers. Run the following command to generate the mail notification:

php artisan make:mail NewBlogPostNotificationMail

Open the generated NewBlogPostNotificationMail.php mail notification file located in the app/Mail directory. Modify it to format and send the email:

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class NewBlogPostNotificationMail extends Mailable
{
    use Queueable, SerializesModels;

    public $emailData;

    public function __construct($emailData)
    {
        $this->emailData = $emailData;
    }

    public function build()
    {
        return $this->view('emails.new-blog-post-notification')
            ->subject('New Blog Post Published: ' . $this->emailData['title']);
    }
}

Conclusion:

In the intricate dance of software architecture, the Observer pattern stands as a choreographer, guiding the interplay between objects while upholding the sanctity of loose coupling. In the embrace of Laravel's event system, this pattern finds its canvas, orchestrating a symphony of communication that's both elegant and modular. By delving into the intricacies and potential of the Observer pattern, developers can gracefully traverse the landscape of object synchronization, crafting systems that communicate harmoniously while adhering to the principles of flexibility and maintainability. The Observer pattern, within the realm of Laravel, stands as a testament to the power of patterns, where elegant design harmonizes with the art of coding.

Tags

Anurag Deep

Logical by Mind, Creative by Heart