Pergunta

Como qualquer padrão de design o Padrão de especificação é um ótimo conceito, mas suscetível ao uso excessivo por um arquiteto/desenvolvedor ansioso.

Estou prestes a iniciar o desenvolvimento em um novo aplicativo (.NET & C#) e realmente gosto do conceito do padrão de especificação e estou ansioso para fazer pleno uso dele. No entanto, antes de ir em todas as armas em chamas, eu estaria realmente interessado em saber se alguém poderia compartilhar os pontos problemáticos que experimentaram ao usar o Padrão de especificação no desenvolvimento de um aplicativo.

Idealmente, estou procurando ver se outras pessoas tiveram problemas em

  • Escrevendo testes de unidade em relação ao padrão de especificação
  • Decidindo em qual camada as especificações devem viver (repositório, serviço, domínio, etc)
  • Usando -o em todos os lugares quando um simples if declaração teria feito o trabalho
  • etc?

desde já, obrigado

Foi útil?

Solução

Como David apontou em seu comentário, muito do que é útil na especificação agora pode ser mais sucintamente alcançado com nomes como Linq.

Em vez de um novo tipo de especificação, você pode criar especificações arbitrárias em voar:GetCustomers().Where(customer => customer.IsActive && customer.City == "Oakland");

Este não é um substituto completo para a especificação, no entanto, por alguns motivos:

  1. A classificação/filtragem ocorre na aula de consumo depois de devolver todos os clientes. Se você está lidando com qualquer outra coisa que não seja objetos na memória, isso é subótimo (Linq-to-SQL e similares são exceções porque eles compilam e otimizam consultas e as executam no servidor/lado remoto, retornando apenas os resultados desejados ).
  2. Sua API é aberta para algum Consulta se você expor coleções e deixar a especificação para as consultas LINQ. Se você deseja restringir o que ou quanto pode ser recuperado, precisará de um conjunto de especificações para consultar.

Certamente não há necessidade de usá -lo em todos os lugares, e é muito possível que você não precise; Não conheço seu domínio ou no que você está trabalhando.

Eu acho que o melhor conselho não é olhar para usá-lo. Você verá quando é garantido, provavelmente quando começar a escrever uma aula que se parece com o primeiro exemplo no artigo ao qual você vinculou.

Apenas mantenha -o no seu repositório de padrões mentais para que você tenha se precisar; Se você nunca o usa, isso significa apenas que você não precisava, e tudo bem.

A escolha da camada está sujeita à natureza das especificações e ao uso. Em muitos casos, eles são ajudantes para apoiar uma camada de serviço, mas em alguns casos encapsulam a lógica do domínio.

Quanto aos testes de unidade, lembre -se de que suas especificações são unidades ou contêm unidades. Não teste um método que aceite uma especificação com todas as combinações possíveis de especificação; Teste as especificações para garantir que elas se comportem conforme o esperado e, em seguida, você pode reutilizar as mesmas especificações com confiança em muitos métodos e classes.

Espero que seja um pouco útil.

Outras dicas

Não acredito que o LINQ seja um substituto para o padrão de especificação. Lembre -se de que uma especificação é melhor usada para encapsular a lógica de negócios. Portanto, se um dos meus requisitos de negócios me fizer obter todos os clientes valiosos para vários recursos, minha instrução LINQ pode parecer esta:

var valuedCustomers = Customers.Where(c => c.Orders.Count > 15 && c.Active).ToList();

Posso digitar essa declaração em todo o meu aplicativo, mas e se eu quiser anexar a essa regra que o cliente deve ter aderido antes de alguma data? Bem, agora tenho que ir por todo o meu aplicativo e alterar o LINQ. Ou se meu gráfico de objetos mudar (embora esse não deva ser o único motivo para usar o padrão). Quando, em vez disso, eu poderia fazer algo assim

var valuedCustomers = Customers.Where(new ValuedCustomerRule.IsSatisfied()).ToList();

Concordo que o padrão é usado demais, mas é muito útil para as regras de negócios que aparecem em todo o seu sistema para que você não seja mordido quando essas regras mudarem. Para mim, é semelhante a deixar consultas SQL em todo o seu código de aplicativo.

Resposta atualizada: Concordo com o WIX, o LINQ não substitui o padrão de especificação. Não tenho reputação suficiente para adicionar comentários à resposta do Wix, estou apenas respondendo como uma resposta.

Conforme este papel As especificações são usadas principalmente para corresponder a um objeto de domínio com uma declaração. Embora as especificações retornem verdadeiras/falsas ao corresponder a um objeto de domínio, mas isso significa que as especificações são propostas para encapsular qualquer condição booleana em seu código.

Vou levar mais adiante a resposta de Wix. Se você tem uma especificação de valor valuedcustomer, terá uma posição diferente para usar a regra:

   var valuedCustomer = new ValuedCustomerSpecification();
   //1. You can use this statement to check if a customer is valued or not in your domain
   Customer customer = ....
   if(valuedCustomer.IsSatisfiedBy(customer))

   //2. You can use it to get just valued customers from repository, 
   var valuedCustomers = repository.Get(valuedCustomer);

   //3. You can combine it with other specifications to create composite specifications. Following syntax can vary with implementation
   var seniorValuedCustomer = valuedCustomer.And(seniorCustomer)

Meu entendimento de papel é que o usuário pode interagir com as especificações para atingir seus objetivos, desde que exista a necessidade e a interface do usuário do aplicativo permite.

O artigo acima mencionado também menciona quando não usar padrões de especificação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top