Created
January 24, 2019 17:01
-
-
Save yourwebmaker/b9406717c62de0c42275e2cf176065a1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Application | |
{ | |
//O objectivo 'e deixar as camadas mais acima, mais limpas o possivel | |
// e nao saber o que acontece depois... envio de email, disparo de notificacao, sms, etc | |
//como vc pode ver, o controller, so tem 1 dependencia: CommandBus | |
class UserController | |
{ | |
public function __construct(CommandBus $commandBus) | |
{ | |
//Um command bus 'e um servico que vai manipular os comandos que vc manda pra ele | |
//ele pode fazer um commando chamar outro commando tbm e por ai vai... pesquise sobre esse cara. | |
$this->commandBus = $commandBus; | |
} | |
public function register(Request $request) : void | |
{ | |
//aqui vc colocaria a validacao do request | |
//if (dados do usuario cagado, nao continua) { return; } | |
//aqui vc registra o usuario simplemente instanciando um comando. | |
//imagine que um comando 'e como toda acao de escrita que ha no seu sistema | |
//pra cada use case, um commando. | |
//parece coisa demais, mas quando o sistema ta grande, 'e melhor ter mais classes | |
//do que abstracoes zuadas. | |
$this->commandBus->handle(new RegisterUserCommand($request->email, $request->password)); | |
} | |
} | |
// o commando em si. | |
// uma classe de commando e' como um DTO | |
class RegisterUserCommand | |
{ | |
public $email; | |
public $password; | |
} | |
// cada commando precisa de um handler | |
// esse handler vai encapsular a instanciacao dos seus objetos de dominio | |
// vc pode colocar validacoes aqui tbm | |
class RegisterUserHandler | |
{ | |
private $userRepository; | |
public function __construct(UserRepository $userRepository) | |
{ | |
$this->userRepository = $userRepository; | |
} | |
public function handle(RegisterUserCommand $command) : void | |
{ | |
$id = $this->userRepository->getNextId(); | |
$existentUser = $this->userRepository->finbByEmail($command->email); | |
if ($existentUser) { | |
throw new RuntimeException("Usuario ja existente com email {$command->email}"); | |
} | |
$this->userRepository->save(new User($id, $command->email, $command->password)); | |
} | |
} | |
} | |
namespace App\Domain | |
{ | |
/* | |
* Classe the dominio. | |
* Essa classe 'e responsavel por disparar os eventos. | |
* Independente de onde vc instancie um usuario, ele vai disparar eventos | |
*/ | |
class User | |
{ | |
private $id; | |
private $email; | |
private $password; | |
public function __construct(int $id, string $email, string $password) | |
{ | |
$this->id = $id; | |
$this->email = $email; | |
$this->password = $password; | |
// Esse methodo grava os eventos do seu dominio | |
$this->record(new UserWasRegistered($id, $email, $password)); | |
} | |
} | |
// Classe que representa um evento no seu Dominio. | |
// Cada evento pode ser manipulado por varios Handlers | |
class UserWasCreatedEvent | |
{ | |
private $id; | |
private $email; | |
private $password; | |
public function __construct(int $id, string $email, string $password) | |
{ | |
$this->id = $id; | |
$this->email = $email; | |
$this->password = $password; | |
$this->record(new UserWasRegistered($id, $email, $password)); | |
} | |
} | |
//classe que persiste seus objectos de dominio. | |
//Pesquise sobre esse padrao | |
class UserRepository | |
{ | |
public function save(User $user) : void | |
{ | |
//codigo que salva o usuario no banco, ou somente chame o EntityManager do Hibernate | |
} | |
} | |
} | |
namespace App\Infra | |
{ | |
//Classe que manipula o evento disparado pelo dominio | |
class NotificationEventHandler | |
{ | |
private $notificationService; | |
public function __construct(NotificationService $notificationService) | |
{ | |
$this->notificationService = $notificationService; | |
} | |
public function handle(UserWasRegistered $userWasRegistered) | |
{ | |
//dispara a mensagem | |
$this->notificationService->dispatch(new Message( | |
"Usuario com email {$userWasRegistered->email} foi registrado" | |
)); | |
} | |
} | |
// Servico de notificacao | |
class NotificationService | |
{ | |
public function dispatch(Message $message) : void | |
{ | |
} | |
} | |
// Servico de email | |
class EmailServiceHandler | |
{ | |
//vc pode consumir o mesmo DomainEvent (UserWasRegistered) para fazer diferentes coisas como disparo de emails | |
public function handle(UserWasRegistered $event) | |
{ | |
//enviando email | |
} | |
} | |
class SMSServiceHandler | |
{ | |
public function handle(UserWasRegistered $event) | |
{ | |
//enviando SMS | |
} | |
} | |
class BlahServiceHandler | |
{ | |
public function handle(UserWasRegistered $event) | |
{ | |
//enviando qualquer coisa | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment