Modular Application Architecture - Events

Modular Application Architecture - Events


application and components

Event Dispatcher

  1. The application core throws events. To make the system more flexible and performant events have a name, so event listeners (plugins) can register on specific events without having to listen to each single event thrown by the core.
  2. The events might have a payload. A payload contains information associated to the event, making it more meaningful. In this way plugins have more info about the context where the event was thrown as just the name could be not enough.
  3. Event listeners can return some data back to who has thrown the event. The returned data should be in a format that can be understood by the who has thrown the event.

Event features

Event listener registration

Example implementations

<?php
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;

// the event and payload
class SidebarEvent extends Event
{
    private $placement;
    private $items = [];
    public function __construct($placement)
    {
        $this->placement = $placement;
    }

    public function getPlacement()
    {
        return $this->placement;
    }

    public function addItem(Item $item)
    {
         $this->items[] = $item;
    }

    /**
     * @return Item[] 
     */
    public function getItems() : array
    {
        return $this->items;
    }
}


// listeners/plugins
$addContactListener = function (SidebarEvent $ev) {
    $ev->addItem(new Item('Contact on the ' . $ev->getPlacement()));
};
$addHomeListener = function (SidebarEvent $ev, $eventName, EventDispatcher $dispatcher) {
    $ev->addItem(new Item('Homepage' . $ev->getPlacement()));
};

// here is the application
$dispatcher = new EventDispatcher();

// listener registration
$dispatcher->addListener('site_bar', $addContactListener, -100); // priority
$dispatcher->addListener('site_bar', $addHomeListener);

// application throwing events
$dispatcher->dispatch('site_bar', $event = new SidebarEvent('left'));
$items = $event->getItems();

// example use the return values
echo "<li>";
foreach ($items as $item) {
    echo "<ul>" . $item->getTitle() . "</li>";    
}
echo "</li>";
<?php

use App\Events\SidebarEvent;  

// the event and payload
class SidebarEvent
{
    private $placement;
    public function __construct($placement)
    {
        $this->placement = $placement;
    }

    public function getPlacement()
    {
        return $this->placement;
    }
}

// listeners/plugins
$addContactListener = function (array $payload) {
    list($ev) = $payload;

    return 'Contact on the ' . $ev->getPlacement();
};
$addHomeListener = function ($payload) {
    list($ev) = $payload;

    return 'Homepage on the ' . $ev->getPlacement();
};

// listener registration
Event::listen('site_bar', $addContactListener);
Event::listen('site_bar', $addHomeListener);

// application throwing events
$items = Event::fire('site_bar', [new SidebarEvent('left')]);

// example use the return values
echo "<li>";
foreach ($items as $item) {
    echo "<ul>" . $item . "</li>";    
}
echo "</li>";
<?php

// listeners/plugins
$addContactListener = function ($placement) {
    echo "<ul>Contact on the $placement</li>";
};
$addHomeListener = function ($placement) {
    echo "<ul>Homepage on the $placement</li>";
};

// listener registration
add_action('site_bar', $addContactListener); 
add_action('site_bar', $addHomeListener);

// application throwing events

echo "<li>";
$returnPageView = do_action('site_bar', 'left');
echo "</li>";

Conclusion

Comments

Popular posts from this blog

A Tailwind CSS Preset for Laravel 5.5

Short and safe array iteration

PHPStorm's performance