Specification Patner nos Serviços de Domínio.

Historinha:

Wilson Santos
Sep 8, 2018 · 3 min read

O Objetivo principal desse padrão é reaproveitar regras de negocio, mas alem do reuso simples, temos uma questão de desacoplamento envolvida que é boa e ruim ao mesmo tempo. Quando tiramos algumas validações de negocio da classe Raiz podemos mante-la mais simples mais aderente ao seu propósito, mais pura, e por outro lado podemos implementar comportamentos mais complexos em formato de especificações, estas podem ser combinadas com outras especificações, gerando um bom nível semântico de código. Pense em processos como de Aluno e Turmas em processos de Matricula , Cargas , e Locais Adequados para armazenamento e transporte, verificações de Unicidade em seus meios de Persistência , tudo isso pode ser feito em Especificações de domínios mantendo os objetos menos acoplados entre si.

Atenção , Isso pode facilmente nos levar a desrespeitar os princípios S.O.L.I.D , por exemplo o principio da Responsabilidade unica, que diz que uma classe deve ter apenas uma razão para ser alterada , então devemos nos perguntar antes de levar uma regra de negocio para uma especificação se não estamos retirando dela algo que seja de sua responsabilidade, alem disso devemos entender que é responsabilidade de uma classe manter seu estado valido. Esse padrão e apresentado e discutido por dois gigantes (Eric Evans e Martin Fowler) nesse artigo.

Exemplo:

Não vou pensar aqui em exemplos de negocio que sejam os melhores para apoiar a introdução que fiz, pois para isso precisaria aumentar muito a complexidade do exemplo, então vou usar uma coisa mais simples , vamos imaginar uma simples validação de unicidade.

Uma vez que entendamos esse processo ai podemos implementa-los em cenários mais complexos.

Observem que temos uma classe que implementa um interface Genérica “ISpecification” com o Método “IsSatisfiedBy” , nela implementamos a regra que Satisfaz a Especificação Nome único, eu gosto bastante da Semântica que isso proporciona.

a especificação é adicionada a uma Lista de Especificações , essa lista esta sendo controlada pela classe ValidatorSpecification , adicionamos uma especificação é uma mensagem de erro para a mesma, podemos adicionar varias especificações , e todas precisaram ser validas para o Objetos Sample estar valido.

no serviço de domínio podemos chamar a classe de validação que armazena o conjunto de especificações e com base no Método “Validation” , verificar se todas as especificações da lista atentem o método “IsSatisfiedBy”, esse mecanismo genérico é possível graças ao Polimorfismo , com a ajuda das interfaces garantimos que todas as classes do tipo Especificação implementam esse método e por consequência a validação foi desenvolvida pensando na abstração de uma especificação e não nas diversas possíveis implementações.

Assim podemos iterar em uma lista e chamar o método “IsSatisfiedBy” de cada especificação presente na Lista, aqui ainda poderíamos aumentar a complexidade criando métodos que permitissem a combinação de Especificações combinadas com o operador lógico or.

No Framework que esta no git existe uma variação da implementação para Warning e Confirmações

Verificações simples depois da chamada do método “Validate” são realizadas ,normalmente em Serviços de Domínio , essas verificações interporem o fluxo do programa, e setando algum objeto de transporte, no meu caso “ValidationResult”, esse objeto navega entre as camadas e assim temos uma forma de não usar throws diminuindo o custo do processo, usar throw é a pior escolha que podemos fazer para interromper um fluxo de execução pois gerar um custo muito alto para o webserver. Por fim podemos levar essa informação até as camadas de interface e mostrar então mensagens para o usuário.

algumas implementações eu abstrai e encapsulei para reuso (vocês podem encontra-las no meu github)

01-) ValidatorSpecification<T>

02-) Rule<T>

03-) ISpecification<T>

Wilson Santos

Written by

Nos últimos 15 anos, venho desenvolvendo , aperfeiçoando e integrando sistemas, sou apaixonado por desenvolver e ensinar, nem tanto por escrever!.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade