There are multiple advantages and disadvantages of using jobs / commands. One of the advantages is that you can easily reuse a command for example @mehany mentioned that you can use the same RegsiterUser job to register a user both on your registration page and on your administration page.
There are two other nice advantages of using jobs / command (I'm going to call them commands from now on). When using commands you often use a CommandBus to dispatch, or handle, the command. Laravel is shipped with a default implementation of the bus, another implementation is Tactician (If you want to read more about the command bus then you should read their documentation, it's pretty good :) ).
Using the command bus has the advantage that you can use middlewares that are executed before your command is handled. For example I could have a logging middleware that logs the name of each command and the name of the user that is currently logged in whenever a command is handled by the command bus.
Another middleware example is a transaction middleware which would look something like this:
<?php
use Illuminate\Database\DatabaseManager;
class UseDatabaseTransactions {
/**
* DatabaseManager
*/
private $db;
/**
* Use the
*/
public function __construct(DatabaseManager $db)
{
$this->db = $db;
}
/**
* Wrap the execution of a command inside of a database transaction
*
* @param $command
* @param \Closure $next
* @return mixed
*/
public function handle($command, $next)
{
return $this->db->transaction(function() use ($command, $next)
{
return $next($command);
});
}
}
By using this middleware whenever a command has made changes to the database, but throws an exception later on, then the state of the database will be reverted.
Middleware can be a really nice tool to have and will act on all commands.
Another nice advantage is that Laravel has the ShouldQueue interface. By adding this interface to your command it will be automatically put on the queue. This is great if your have a command whose only responsibility is notifying some service. As an example: at a current project I have a NotifyWebmaster($companyId, $email) command that adds a webmaster account to our Intercom app. This command is placed on the queue so that the user does not have to wait for a response of the intercom api.
In one project we only used commands inside of our controllers which made our controllers very thin and easily understandable. But it came with the disadvantage that in order to add a new feature you had to write some additional boilerplate code that would not have been necessary without the commands.
In the end I personally belief this was worth it since it added much more consistency to our codebase.
Ross Tuck has a really nice presentation about this concept called Models & Service Layers; Hemoglobin & Hobgoblins
, you should probably go and watch it. :)
I haven't gone into whether a command should return something, which is a topic of its own. If you're interested in this topic you should look up CQS (Command Query Seperation) and CQRS (Command Query Responsibility Segregation)