Validando regras de negócio em C# com specification pattern

Henrique Dal Bello
Training Center
Published in
3 min readMay 13, 2019

Quem nunca se perdeu com as dezenas de regras de negócio de um projeto que atire a primeira pedra!

Muitas vezes por conta do projeto possuir uma regra de negócio complexa e com muitas validações, acabamos nos perdendo no meio do código e deixando-o mal organizado, e até tornamos pior a legibilidade dele.
O que queríamos deixar fácil acaba se tornando algo maçante e desanimador, tanto para nós, quanto para o próximo a mexer naquele pedaço de código.

Há algum tempo atrás o grande MVP e hoje diretor na Microsoft, Eduardo Pires, me trouxe a tona um tal de Specification pattern que ajudou DEMAIS a reorganizar todas aquelas regras.

A ideia deste pattern é deixar o código bem mais atômico (vide conceito de SOLID), ajudando-nos a reutilizar código e tornar bem mais legível e intuitiva as nossas validações de regras de negócio.

Mas chega de papo e vamos ver um pouco de código!

Considere uma entidade Pessoa -Person:

Precisamos validar algumas informações antes de inseri-las em nosso Afinal, é melhor validar do que deixar estourar uma exception por parte do banco de dados, não?

Além disso, deixar sempre por conta do nosso front-end pra validar essas informações pode ser um tanto ruim, já que ainda hoje é bem possível burlar alguns formulários.

Vamos montar nosso método Add que vai inserir uma pessoa no nosso banco de dados, pra isso vamos validar dentro do próprio método:

Perceba que precisamos de vários ifs para validar se nossa entidade está OK, desde validações pra identificar se não está nulo, até algumas mais especificas como: Tamanho do campo CPF em 11 e ser um número (poderíamos usar regex ali também).

Funciona certo? Mas… e se usarmos o specification pattern com a biblioteca DomainValidation desenvolvida pelo Eduardo Pires? O que conseguimos melhorar?

Começamos baixando o pacote diretamente pelo NuGet explorer:

E agora vamos criar nossas especificações. Basicamente elas vão ser exatamente os nossos ifs do código anterior:

E com elas fazemos nossa validação, deixando nossa service da seguinte maneira:

Assim deixamos nosso método muito mais limpo e conseguimos cumprir o conceito de atomicidade do SOLID, podendo reutilizar nossas specifications em qualquer outra validação!!

Cumprimos nosso objetivo, mas vamos mais além!

Como bônus quero refatorar essas nossas especificações, pois é ruim ficar com várias delas só pra fazer um string.IsNullOrWhiteSpace() não?

Então bora fazer de um jeito bem mais fácil usando lambda expressions:

Reduzimos pra apenas duas (e totalmente reutilizáveis) especificações!!
E se olharmos a classe IsPersonValid ainda podemos entender tranquilamente o que estamos validando.

Generics e lambda expression são sensacionais!

--

--

Henrique Dal Bello
Training Center

Knowledge is for sharing. Developing bugs since 2012 💻