The difference between commands and events

[...], 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

[...] 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.

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

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?

[...] 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: