Command Bus pattern

Laravel Brussels Meetup July 2015

Laravel Brussels Meetup July 2015

Jonathan Van Belle
aka

@Grummfy

Laravel Brussels Meetup July 2015

  • What's command bus pattern
    • Advantages
    • "Drawback"
  • Alternative to this pattern
  • Existing solution
  • Demo time

Laravel Brussels Meetup July 2015

What's command bus pattern

Laravel Brussels Meetup July 2015

What's command bus pattern

  • Command: message
    • data
  • Command Bus: dispatch the message
    • direct, queues, networks, ...
  • Handler: use the message to do something
    • save to db
    • log
    • mail
    • ...

Laravel Brussels Meetup July 2015

What's command bus pattern

Bus

Command

Handlers

Bus : handle this command

Laravel Brussels Meetup July 2015

Advantages

  • Related to DDD
  • Decouple/Reuse code
  • Mainly small code
  • Controller become testable
  • At the end
    • code taste good
    • easier to test
    • easier to refactor

Laravel Brussels Meetup July 2015

Drawback

  • Another abstraction layer
  • Glue time
    • use DI
  • More class
  • Need to change habits

Laravel Brussels Meetup July 2015

Alternative to this pattern

  • Depending of the context and requirements
  • queues
    • interesting to mix it in the command bus
  • event
    • Tell something has happened VS needs to happen
    • Have multiple listeners
    • can also be combined

Laravel Brussels Meetup July 2015

Existing solution

  • league/tactician
    • xtrasmal\tactician-provider
    • jildertmiedema/laravel-tactician
  • simple-bus/message-bus
  • Laravel:
    • Command
    • ShouldBeDispatch/ShouldBeQueued
  • At the hand, it's convention!
    • Command: interface
    • Command Bus: dispatcher
    • Handlers: interface

Laravel Brussels Meetup July 2015

Existing solution

<?php
class CommandBus
{
  protected $_handlers = array();
  public function __construct($handlers)
  {
    $this->_handlers = $handlers;
  }

  public function handle($command)
  {
    $name = get_class($command);
    if (!isset($this->_handlers[ $name ]))
    {
      throw new UnexpectedException('No handler for the given command ' . $name);
    }

    $this->_handlers[ $name ]->handle($command);
    // only one => use decorator to make onion
  }
}

Laravel Brussels Meetup July 2015

Existing solution

  • Can be made at the hand easily
  • BUT existing
    • have a lot of plugins
    • have a community
    • is less work to do

Laravel Brussels Meetup July 2015

Example of usage

With decorator (make an onion of handlers)

  • log all command
  • transact on all query command
  • try/catch all command
  • valid command
  • slack all command
  • time mesure
  • ...

Laravel Brussels Meetup July 2015

Demo time

Advice

  • Use explicit name
  • Don't overuse it
  • Keep it simple
  • Mix it with event and queues
  • Think to "do this"
  • Try in js too ;)
    • https://github.com/MadeHQ/CommandBus
    • https://gist.github.com/danharper/87269a0628ed97fb026e

Laravel Brussels Meetup July 2015

Resources

  • http://php-and-symfony.matthiasnoback.nl/2015/01/some-questions-about-the-command-bus/
  • http://laravel.com/docs/5.0/bus
  • http://culttt.com/2014/11/10/creating-using-command-bus/
  • http://www.reddit.com/r/PHP/comments/29a6qz/what_am_i_missing_with_this_whole_command_bus/cij6avo
  • http://shawnmc.cool/command-bus
  • Use your favorite web search engine with "command bus php"

Laravel Brussels Meetup July 2015

Made with Slides.com