PHP & Symfony About PHP and Symfony2 development

Lean publishing "Principles of Package Design"

Posted on by Matthias Noback

During the great PHP Benelux Conference 2015 edition I published the final version of Principles of Package Design. Let me tell you a little bit about its history and some of the things I had to deal with.

A bit of history

My first book, A Year With Symfony, was released on September 4th, 2013. Just 6 days later, I started working on Principles of PHP Package Design. As it turned out, it was quite hard to keep the process going. There were several months in which I wrote nothing at all. Sometimes I picked up the work, but then I had completely lost my track and tried to get back on it by revising existing chapters over and over again. Meanwhile all kinds of other projects begged for attention as well, including the release of the backend project of the new nos.nl website, the preparations for the Hexagonal architecture training and the birth of our daughter Julia ;)

Finally, I took a couple of weeks to focus completely on the book, and as it turned out, there wasn't really much work left. The final sprint consisted mainly of preparing the book interior for print, designing the cover, and thinking of a good way to release it. The PHP Benelux conference seemed like a good place and time to do this. I felt comfortable enough to do it there, given I am familiar with many of the attendees.

Lean/live publishing

Still, I was quite nervous to actually do this. Even though I did it before, to publish a Leanpub book in real-time is always a bit scary. But I pushed the "Publish" button nonetheless, and everything turned out well. While Leanpub was generating fresh PDF, MOBI and EPUB files, I talked a bit about lean publishing and its up- and downsides.

The main take-aways from this are:

It's great to be able to publish early, and let readers give you feedback. But make some kind of a commitment to finish the book as well. Imagine the early adopters standing in front of you, asking you when you'll finish it and give an honest answer:

Early adopters demanding a finished book, source: https://www.gov.uk/government/news/farewell-reception-for-201213-chevening-scholars

Proof reading

Also, make sure to ask people to read the book before you publish it, and provide you with some feedback. Any feedback is helpful, and also any type of reader: an experienced or an inexperienced programmer, a native English speaker, or a non-native one, etc.

One example of highly useful feedback I got from Peter Bowyer (rephrased):

It seems like you're trying to put two books into one. In the first place there's lots of information about practical PHP package development, working with Git, GitHub, Composer, Packagist, etc. Then there's also lots of information about software design and design principles, which is more theoretical of nature.

This particular comment struck me like lightening and helped me decide to leave out all the PHP-specific things and turn this into a general programming book. I'm really curious how this works out. So far it turns out that people really get a lot of practical advice from it, as well as many things to think about, while they're doing their job.

Also, because it took me about one and a half years to finish this book, its style was not really consistent at first. While re-reading the older parts it turned out that I took certain things for granted, sometimes underestimated, sometimes overestimated the audience, sometimes let myself get away with shortcuts, or obscure explanations. All of these mistakes have now been taken care of, again thanks to proof readers who pointed them out to me.

Print edition

When I published A Year With Symfony, the printed edition was really an after-thought. It turned out that preparing a book for print can be a lot of work. In those days I used Lulu, but it was such a hassle to prepare the PDF for distribution (in particular for sales channels like Amazon), that I decided to not do the same thing for Principles of Package Design. For this book, the printed edition is just as important as the digital one. And everything is better now since I use CreateSpace, which is actually an Amazon product. They offer print-on-demand and proper shipping costs for people all over the world. Anything you upload is manually, yet quickly verified and their in-browser software is just very friendly to use. The royalty percentage is about 40% which is not the best out there, but to me quite reasonable given that there's no further effort required from you after you publish the book.

The print edition is available on the different Amazon websites, e.g. amazon.com, amazon.de and amazon.co.uk

Feedback wanted

If you have read this book, or are reading this book. Please provide me with any feedback that you have. I'm also looking for some feedback that I can add to the book's landing page on leanpub.com, so if you have a nice quote, please send me an email.

Finally, to celebrate the release, you can use the following discount link to buy the book for $19: leanpub.com/principles-of-package-design/c/phpbnl15

Encouragements

Despite the dangers of lean publishing: if you feel the slightest inclination towards writing your own book, I advise you to do so. Even as an experiment, just like an experimental open source library, you can just start working on it, and later decide whether or not it's something worth finishing. The experience itself is useful, and sharing your knowledge of a particular subject is useful for more people than you may imagine. I especially like to recommend the Leanpub platform since it's very easy for technical people to get up and running with it.

Categories: PHP Book

Tags: design principles reuse Principles of PHP Package Design slides

Comments: Comments

Collecting events and the event dispatching command bus

Posted on by Matthias Noback

It was quite a ride so far. We have seen commands, command buses, events and event buses. We distilled some more knowledge about them while formulating answers to some interesting questions from readers.

Why you should not dispatch events while handling a command

In a previous post we discussed a sample event (the UserSignedUp event):

class UserSignedUp implements Event
{
    public function name()
    {
        return 'user_signed_up';
    }

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

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

An instance of such an event can be handed over to the event bus. It will look for any number of event handlers that wants to be notified about the event. In the case of the UserSignedUp event, one of the interested event handlers is the SendWelcomeMailWhenUserSignedUp handler:

class SendWelcomeMailWhenUserSignedUp implements EventHandler
{
    ...

    public function handle(Event $event)
    {
        $user = $this->userRepository->getById($event->userId());

        $this->userMailer->sendWelcomeMailTo($user);
    }
}

The UserSignedUp event occurs whenever a SignUpUser command has been handled. We might be tempted to inject the event bus into the command handler and let it handle the event immediately:

class SignUpHandler
{
    public function __construct(EventBus $eventBus, ...)
    {
        $this->eventBus = $eventBus;
        ...
    }

    public function handle($command)
    {
        ...

        $this->userRepository->add($user);

        $event = new UserSignedUp($user->id());

        $this->eventBus->handle($event);
    }
}

We should not forget however that this command is handled within a database transaction created by one of the command buses. And as I already mentioned, we don't want the event to be handled within the same transaction, since it could endanger the success of that transaction. Also, when the transaction fails in the end, we might end up handling an event for entities whose actual state is insecure.

So instead, we should merely collect events while handling the command and only hand them over to the event bus when the transaction was committed, i.e. when we know that the command has been successfully and completely handled.

Event providers

Of course, SimpleBus would not be complete without an out-of-the-box implementation of this kind of delayed event handling. The connecting concept between events and the command bus is the ProvidesEvents interface, which is part of the SimpleBus/EventBus package.

namespace SimpleBus\Event\Provider;

use SimpleBus\Event\Event;

interface ProvidesEvents
{
    /**
     * @return Event[]
     */
    public function releaseEvents();
}

You can provide a simple implementation for such an EventProvider by defining a class for it, which uses the trait EventProviderCapabilities. This adds the ability to collect events (using the raise() method) and release them later, using the releaseEvents() method:

use SimpleBus\Event\Provider\EventProviderCapabilities;

class EventProvider implements ProvidesEvents
{
    use EventProviderCapabilities;
}

We could inject this EventProvider into any command handler and use the raise() method of the EventProvider to raise new events (which will not be handled right-away, but only stored in-memory):

class SignUpHandler
{
    public function __construct(EventProvider $eventProvider, ...)
    {
        $this->eventProvider = $eventProvider;
        ...
    }

    public function handle($command)
    {
        ...

        $event = new UserSignedUp($user->id());

        $this->eventProvider->raise($event);
    }
}

Now, at what point could we safely release the events collected by the EventProvider and hand those events over to the event bus? The answer is: in yet another command bus! We simply wrap the new event-aware command bus which starts and commits the database transaction. Only then can we be sure that the transaction was successful and we can proceed to safely dispatch the collected events.

Since SimpleBus/CommandBus and SimpleBus/EventBus are stand-alone packages, I introduced a bridge package between the two, SimpleBus/CommandEventBridge. It contains this class, which is a CommandBus, but asks the event provider to release its events, and lets the EventBus instance handle them:

class DispatchesEvents implements CommandBus
{
    use RemembersNext;

    private $eventProvider;
    private $eventBus;

    public function __construct(ProvidesEvents $eventProvider, EventBus $eventBus)
    {
        $this->eventBus = $eventBus;
        $this->eventProvider = $eventProvider;
    }

    public function handle(Command $command)
    {
        $this->next($command);

        foreach ($this->eventProvider->releaseEvents() as $event) {
            $this->eventBus->handle($event);
        }
    }
}

In a diagram this would look something like this (from left to right it shows you the passage of time):

Diagram

Conclusion

After reading this series about command and event buses, you can start using commands to interact with your application and events to act upon the things that happened. Because both the command and the event bus are highly extensible you have many options for introducing more advanced behavior. You could think of:

  • Collecting events in an store
  • Handling commands asynchronously
  • The same for events
  • ...

For now we are more or less done talking about command and event buses. If you have questions, just write a comment below this post. I'm currently working on version 2.0 of the SimpleBus packages. You can at least expect a new post when I'm done, to announce the changes with respect to 1.0. To give you a sneak peek:

  • Code for command and event buses will be generalized and bundled in the MessageBus package.
  • Instead of wrapping message buses using composition, this new package introduces the concept of message bus middlewares, offering greater flexibility and cleaner code for your own specialized message bus features.

Categories: PHP

Tags: hexagonal architecture commands command bus events event bus SimpleBus

Comments: Comments

Some questions about the command bus

Posted on by Matthias Noback

So far we've had three posts in this series about commands, events and their corresponding buses and handlers:

Now I'd like to take the time to answer some of the very interesting questions that by readers.


The difference between commands and events

Robert asked:

[...], could you possibly explain what are the main differences between a command bus and an even dispatcher?

Marc and Florian answered the question already, but I'd like to repeat the answer here. The main difference is: events tell you that something has happened, while a command tells you that something needs to happen. From this it follows that nobody might be interested in an event, but somebody should be interested in a command, because it has to be handled somehow.


Disadvantages of using a command bus

mTorres asked

[...] is it great that you state the advantages but can you also post the disadvantages?

Some suggestions are offered, which also recur in other people's comments:

1) Increases complexity with another layer of abstraction [...]

2) You must glue each command with its handler somewhere and load that information on every request [...] like the DI graph

To respond to the first reason: in my experience the level of complexity drops when you start using commands and the command bus. As mentioned it helps you disentangle the technical details of the input from the domain-specific actions that will be executed in the core of your application. Indeed, this adds a lot of flexibility as well.

The second reason is not a problem either; the number of services in your DI container doesn't affect performance at all. What matters is the number of objects that you actually instantiate. This number is still very low, because the SimpleBus packages provide lazy-loading of command and event handlers out-of-the-box.

One disadvantage that I can come up with myself is that it may require a bit more thinking from the developer (this is not meant to be cynical by the way!). Using commands and events (and also separating command from query responsibilities) generally leads to better design because you think harder about the characteristics of your domain. Still, this takes a bit more effort, which you might not want to put in if the application is not supposed to live a long life (i.e. needs no or just a little bit of maintenance).

One other disadvantage may be that you will have more classes. To me this is more like an advantage, since if the application still does the same thing, this means that those extra classes are highly focused on performing one task well.

One, maybe bigger disadvantage, might be that it's not as simple anymore to offer CRUD-style actions. Commands are task-oriented instead of data-oriented. Still, you should keep in mind that just like you don't need go "DDD-all-the-way", you don't need to use commands everywhere in your application.


The command as constructor argument

Daniel S asked:

[...] why does the Command Handler not receive the actual command in the constructor?

class SignUpHandler implements CommandHandler
{
    public function __construct(SignUpCommand $command) { /* ... */ }
}

Florian answered this one quite nicely:

I really think it should be passed as an argument of the handle() method. Otherwise, one handler instance = one command. You wouldn't be able to process 2 different command instances with the same handler instance.

That's right. A handler itself is an immutable service, which probably needs other immutable services to do its job. Hence, the constructor should be reserved for injecting dependencies. Then the same handler can be used to handle multiple instances of the same type of command.


How to return a value from the command bus

Gabriel Birke asked:

How would the controller know that the signup was successful or not and display the correct message?

That's a very good question. And again, Florian provided some great answers already. Several kinds of problems may occur if we handle a command in the same process:

  • The user may have provided invalid input data
  • The provided input data may result in an invalid state
  • An unexpected runtime error may occur (e.g. network failure)

We can already catch validation errors before we hand the command over to the command bus. In fact, we should verify that the command itself contains valid data and provide human-oriented error messages to the user if it doesn't. The other two kind of problems will result in regular failures, just like they would in a non-command oriented application. They can be handled in any way you like (e.g. allowing the user to retry the action, or show an error page).

Any other execution path should be considered the happy path: everything goes well. So if the command bus finally returns control to the controller that asked it to handle a command, you can assume that no problems occurred and, for instance, redirect to a "thank you" page.

Something that Florian already mentioned as well: when using commands you follow the Command-query separation (CQS) principle: a function is either a query (i.e. it returns something) or a command (i.e. it affects state). Both are mutually exclusive. So a command is not supposed to return anything and a query is not supposed to modify anything.


Could commands handle themselves?

mTorres asked another question which is highly relevant:

[...] maybe we could create Commands that executes themselves (with the __invoke method)? It will be less flexible but you'll have also less complexity to handle, what do you think?

It is an intriguing idea. However, you have to keep in mind that the set of commands that might be able to handle themselves is very small. State machines and situations where command objects are created ad hoc might allow for self-handling commands. See also an example of self-executing commands from Ross Tuck's library Tactician, which has more or less the same goals as SimpleBus.

The notion of self-executing commands recently resulted in an interesting debate when Taylor Otwell demoed the use of self-executing commands in the new version of Laravel. As a follow-up, Ross wrote something which I consider a highly convincing recommendation against the use of these types of commands.

The takeaway of this is that:

  • Commands - as discussed in this series - should be simple messages only.
  • Related behavior should always be separated from the message itself.

Of course, SimpleBus (as well as Tactician) allows you to implement commands in any way, so you could easily replicate Laravel's self-handling commands. In fact, let me just show you a rough outline:

use SimpleBus\Command\Command;
use SimpleBus\Command\Bus\CommandBus;
use SimpleBus\Command\Bus\RemembersNext;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Bus\SelfHandling;

interface HandlesItself extends Command
{
}

class SupportsSelfHandlingCommands implements CommandBus
{
    use RemembersNext;

    private $container;

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

    public function handle(Command $command)
    {
        if ($command instanceof HandlesItself) {
            $arguments = $this->resolveArguments(;
            $this->container->call([$command, 'handle']);

            /*
             * We consider the command handled,
             * so we don't call the next command bus
             */
        } else {
            $this->next();
        }
    }
}

You only need to make sure that this particular command bus is called before any regular command handler might be called.

Conclusion

Thanks everyone for asking these questions. As you can see, there are quite a lot of details and reasoning behind the answers.

The next post will be about collecting events.

If you're interested to learn more about these subjects and start using commands and events in your (Symfony) application, check out my Hexagonal Architecture training website.

Categories: PHP

Tags: hexagonal architecture command bus events event bus SimpleBus

Comments: Comments