Skip to content

Instantly share code, notes, and snippets.

@yourwebmaker
Created January 24, 2019 17:01
Show Gist options
  • Save yourwebmaker/b9406717c62de0c42275e2cf176065a1 to your computer and use it in GitHub Desktop.
Save yourwebmaker/b9406717c62de0c42275e2cf176065a1 to your computer and use it in GitHub Desktop.
<?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