El patrón Observer en PHP

Hoy escribo sobre el patrón Observer en PHP porque esta semana estoy implementando mis primeras apps SPA con React.js y Flux y resulta que Flux no es más que una variante JavaScript de Observer. ¿Qué te parece?

Entonces he pensado, ¿por qué no comparto un ejemplo sencillo de Observer implementado en PHP? Seguro que te ayuda a entender mejor el funcionamiento de Flux si a ti también te interesa aplicar la arquitectura Flux en tus apps frontend.

El patrón Observer en PHP

Este patrón, también conocido con el nombre publicación-inscripción, se utiliza cuando nuestras apps necesitan manejar eventos. La idea es muy sencilla: un objeto (Sujeto) almacena una lista de objetos observadores a los que envía una notificación cuando sucede algún cambio.

Es así como se implementa Flux, donde por un lado está el almacén de datos, el sujeto, que emite eventos cuando cambia el estado de la aplicación, y por otro lado están los componentes React que recogen dichos cambios.

Pero volvamos a PHP.

El patrón Observer está disponible en la Librería Estándar de PHP (Standard PHP Library, SPL) desde la versión 5.1. Concretamente tenemos a nuestra disposición las interfaces SplSubject, SplObserver y SplObjectStorage para implementarlo.

En el siguiente ejemplo implementaremos las interfaces SplSubject y SplObserver:

SplSubject {
    /* Methods */
    abstract public void attach ( SplObserver $observer )
    abstract public void detach ( SplObserver $observer )
    abstract public void notify ( void )
}

SplObserver {
    /* Methods */
    abstract public void update ( SplSubject $subject )
}

Vamos a simular de un modo muy esquemático y sencillo que un blogger escribe un nuevo post en su blog y automáticamente se envía un email a los usuarios suscritos al mismo, ¿vale? Allá va el código.

Blog.php:

class Blog implements \SplSubject
{
    protected $posts = [];
    protected $storage;

    public function __construct()
    {
        $this->storage = new SplObjectStorage;
    }

    public function publish($post)
    {
        $this->posts[] = $post;
        $this->notify();
    }

    public function attach(SplObserver $observer)
    {
        $this->storage->attach($observer);
    }

    public function detach(SplObserver $observer)
    {
        $this->storage->detach($observer);
    }

    public function notify()
    {
        foreach ($this->storage as $observer) {
            $observer->update($this);
        }
    }
}

User.php:

class User implements SplObserver
{
    public function update(SplSubject $subject)
    {
        echo 'Nuevo post publicado, email enviado al usuario!' . PHP_EOL;
    }
}

app.php:

require 'User.php';
require 'Blog.php';

$blog = new Blog;

$blog->attach(new User);
$blog->publish('Este es el nuevo post bla, bla.');

¡Ya está! Al ejecutar el programa:

php app.php

Obtenemos esta salida:

Nuevo post publicado, ¡email enviado al usuario!

Gracias por leer este post, espero que te resulte útil y que lo compartas con tus amigos en tus redes sociales.

También te puede interesar leer esto…