DDD - Lógica de negócios e exceções em entidades


 Hoje veremos como lidar com lógica de negócios e exceções em entidades na abordagem do Domain Driven Design.

No Domain Driven Design as entidades representam os objetos principais dentro de um domínio. Elas encapsulam o estado e o comportamento, permitindo-nos modelar regras e operações de negócios complexas.

A lógica de negócios, como validações, cálculos ou transições de estado, pode ser implementada nas entidades para garantir a integridade e a consistência do domínio.

Vejamos um exemplo de entidade Order em um sistema de comércio eletrônico. A entidade Order pode ter diversas regras de negócios associadas a ela, como garantir que o pedido tenha um cliente válido, contenha pelo menos um item ou atenda a determinados critérios de processamento.

public class Order
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
    public List<OrderItem> Items { get; set; }

    public void AddItem(OrderItem item)
    {
        if (item == null)
        {
            throw new ArgumentNullException(nameof(item));
        }

        // lógica adicional para validação do item
        Items.Add(item);
    }

    // Outros métodos e propriedades
}

A seguir temos algumas diretrizes para lidar com lógica de negócios em entidades :

  1. As entidades devem encapsular a lógica de negócios relacionada a elas. Isso significa que as operações e verificações devem ser definidas como métodos dentro das próprias entidades.
     
  2. Crie métodos na entidade que representam operações significativas no contexto do domínio. Esses métodos devem refletir as ações que fazem sentido para a entidade.
     
  3. Implemente validações de negócios dentro das entidades para garantir que os dados estejam sempre em um estado consistente e válido.
     
  4. As entidades devem ser responsáveis por manter seu próprio estado interno, aplicando as regras de negócios conforme necessário.

Tratamento de exceções

As exceções desempenham um papel crucial no tratamento de erros e na notificação dos clientes sobre cenários excepcionais. No DDD, exceções podem ser usadas para comunicar erros específicos de domínio ou violações de regras de negócios.

Continuando com nosso exemplo de entidade Order, vamos considerar um cenário onde o pedido deve ter um valor total mínimo para processamento. Se o pedido não atender a esses critérios, podemos lançar uma exceção personalizada para indicar a violação.

public class InsufficientOrderValueException : Exception
{
    public InsufficientOrderValueException(string message) : base(message)
    {
    }
}

public class Order
{
    public void Process()
    {
        decimal totalValue = CalculateTotalValue();

        if (totalValue < minimumValue)
        {
            throw new InsufficientOrderValueException("O pedido não atende o valor mínimo.");
        }

        // processa o pedido
    }

    // outros métodos
}

No trecho de código acima, definimos uma exceção personalizada InsufficientOrderValueException para representar a violação específica. Dentro do método Process calculamos o valor total do pedido e verificamos se atende ao requisito mínimo. Caso contrário, lançamos a exceção personalizada com uma mensagem de erro apropriada.

Ao usar exceções personalizadas, podemos diferenciar entre diferentes tipos de erros e tratá-los adequadamente em nosso aplicativo ou propagá-los ao cliente para ações apropriadas.

A seguir temos algumas diretrizes para lidar com exceções em entidades:

  1. Crie exceções personalizadas que reflitam erros ou violações de regras de negócios específicas. Isso ajuda a identificar e lidar com problemas de forma mais precisa.
  2. Se uma operação tentar violar uma regra de negócios, lance uma exceção apropriada. Isso pode ser feito diretamente na entidade ou em serviços que manipulam as operações.
  3. É comum centralizar a lógica de exceção em um local, como um método protegido ThrowIfInvalid em uma entidade, que pode ser chamado antes de efetuar alterações no estado da entidade.
  4. Em certos casos, você pode querer envolver operações com try-catch para capturar exceções específicas. Isso pode ser útil para tratar exceções de forma adequada e manter a consistência do domínio.

Lembre-se de que a consistência do domínio é crucial, e a maneira como você projeta a lógica de negócios e trata as exceções deve refletir a compreensão profunda do domínio e das regras que regem o sistema.

Assim, no Domain-Driven Design (DDD), a camada de domínio é o coração da aplicação, onde reside a lógica de negócios e as regras que definem o comportamento e a semântica do domínio. Portanto, realizar o tratamento de exceções na camada de domínio é uma abordagem coerente por várias razões:

  1. As exceções são frequentemente resultantes de violações das regras de negócios. Colocar o tratamento de exceções na camada de domínio permite que você capture e lide com essas violações diretamente onde elas ocorrem, garantindo a consistência do domínio.
     
  2. As entidades e agregados do domínio conhecem melhor as regras e a lógica de negócios relacionadas a eles. Colocar o tratamento de exceções no domínio permite encapsular a lógica de tratamento de exceções junto com a lógica de negócios, mantendo tudo coeso e autossuficiente.
     
  3.  Ao tratar exceções no domínio, você centraliza o tratamento de erros na parte mais crítica da aplicação. Isso facilita a manutenção, já que todas as regras de tratamento de exceções estão concentradas em um local.
     
  4. O tratamento de exceções no domínio pode ser projetado para refletir as situações de erro específicas do domínio. Isso cria uma semântica expressiva que ajuda a entender os problemas que podem ocorrer dentro do contexto do domínio.
     
  5.  Ao lidar com exceções no domínio, você torna mais fácil testar os cenários de erro durante os testes de unidade. Isso permite que você valide as regras de negócios e os comportamentos de erro em conjunto.
     
  6. Ao tratar exceções no domínio, você isola a camada de domínio da complexidade da infraestrutura, como bancos de dados, APIs externas, etc. Isso mantém sua camada de domínio focada apenas nas regras e na lógica do negócio.
     
  7. Se as regras de negócios mudarem, é mais fácil manter o tratamento de exceções correspondente no mesmo local (ou perto dele) no domínio.

Entretanto é importante ressaltar que nem todas as exceções devem ser tratadas no domínio. Erros de infraestrutura, como problemas de conexão de banco de dados ou falhas de rede, são geralmente tratados em camadas superiores, como a camada de aplicação ou a camada de apresentação, pois essas camadas são responsáveis por lidar com as complexidades técnicas da aplicação.

E estamos conversados...

"E (Jesus) os ensinava, dizendo: Não está escrito: A minha casa será chamada, por todas as nações, casa de oração? Mas vós a tendes feito covil de ladrões."
Marcos 11:17

Referências:


José Carlos Macoratti