Featured image of post Primary card - Command use case

Primary card - Command use case

Hemos llegado al orquestador del flujo o también llamado caso de uso.

Su objetivo es similar que el Query use case, pero en este caso modifica información en lugar de ofrecerla.

Especificaciones

Se diferencia de la Query sólo en la intención del Use case que lo va a gestionar. En este caso, los Commands buscan modificar información del dominio.

Command use case Primary reverse

Aquí se cuecen muchas cosas, con lo que la complejidad puede llegar a ser alta. Al ser el orquestador del flujo, a veces tiene que lidiar con situaciones complicadas. Le damos de complejidad un 6.

Su misión principal es ser el orquestador del caso de uso de escritura.

Como características más concretas, el Command use case conoce lo necesario para conseguir el objetivo de cambiar la información del Domain. Para ello, conoce bien las herramientas y el Domain para conseguir el objetivo. Para liberar responsabilidades, se sirve de Domain services. Por otra parte, al ser una modificación del Domain, necesita ser transaccional para que los elementos del Domain mantengan la coherencia.

Se relaciona con los Commands y Domain services.

Vale la pena agregar como observación que el Command use case necesita ser transaccional, pero como comentamos antes, le podemos delegar esa tarea al Command Bus.

¿Qué valor me aporta implementar un Command use case?

El Command use case es el orquestador de flujo por excelencia del caso de uso. Conoce todos los servicios que necesita y hace uso de ellos para cumplir el objetivo del Command que maneja.

Esta capa tiene que ser muy sencilla, sólo gestionar flujo.

Debemos empujar las cosas que no pertenezcan al flujo, que suelen ser reglas de negocio, a los elementos de la capa de Domain como Domain services, Aggregates o Value objects.

De esta forma no perderemos el objetivo del caso de uso.

¿Cómo se expresa esta carta en el mundo real?

Como indica el icono de arriba a la izquierda, corresponde a una clase.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
final class SignUpUserCommandUseCase implements CommandUseCase
{
    public function __construct(
        private UniqueIdProvider $uniqueUuidProviderService,
        private UserCreator $userCreator,
        private UserRepository $userRepository
    ) {
    }

    /**
     * @throws DomainException
     * @throws PasswordInvalidByPolicyRulesException
     * @throws UserInvalidException
     * @throws UserNameInvalidByPolicyRulesException
     */
    public function __invoke(SignUpUserCommand $command): void
    {
        $userId = $this->uniqueUuidProviderService->generate();

        $user = $this->userCreator->signUp(
            UserId::fromString($userId),
            UserName::build($command->username()),
            Email::build($command->email()),
            Password::build($command->password())
        );

        $this->userRepository->store($user);
    }
}
1
2
TODO: Referencias a otras cartas
TODO: Agregar gráfico de responsabilidades

Licensed under CC BY-NC-SA 4.0
Creado con Hugo
Tema Stack diseñado por Jimmy