2009-09-21 8 views
7

Wikipedia afirma que el patrón Especificación es donde la lógica de negocio puede recombinarse por el encadenamiento de la lógica de negocio juntos usando la lógica booleana. Con respecto a la selección de objetos de filtrado de listas o colecciones, me parece que Dynamic LINQ me permite lograr lo mismo. ¿Me estoy perdiendo de algo? ¿Hay otros beneficios para el patrón de especificación que deberían considerarse también?¿El patrón de especificación está obsoleto cuando puede usar LINQ dinámico?


Editar:

que he encontrado algunos mensajes que hablan de la combinación de LINQ y el patrón Especificación:

Linq Specifications Project

Implementing the Specification Pattern via Linq by Nicloas Blumhardt (Autofac dude)

Alguien ha hecho gone este camino y lo hizo se vuelve complicado de mantener?

+0

Estoy enfrentando esta situación exacta en este momento, por lo que esta pregunta es de gran interés para mí. –

Respuesta

2

dinámico LINQ utiliza expresiones de cadena para permitir la construcción de consulta dinámica. Entonces, de hecho, perdemos el tipo de seguridad allí. Mientras que el uso de patrones de envoltura como el patrón de decorador de su encarnación estrechamente relacionada, el patrón de especificación, nos permite mantener el tipo de seguridad en el código. Exploro utilizando el Patrón Decorador como contenedor de consultas para reutilizar y generar consultas dinámicamente. Puede encontrar el artículo sobre el proyecto de código en: Linq Query Wrappers

O puede consultar mi blog.

5

Soy un C# revelador y les gusta usar el patrón de especificación, porque está más cerca de mi dominio del negocio. Además, no tiene ninguna sorpresa con este patrón, si existe una clase de especificación, debería funcionar. Con Linq, es posible que su proveedor subyacente no haya implementado algunas funciones, y no lo sabrá hasta el tiempo de ejecución.

Pero definitivamente, la mayor ventaja de la especificación sobre LINQ es estar más cerca del negocio, es un mini DSL. LINQ para mí es una DSL para consulta de recopilación, no para el dominio comercial.

1

No sé LINQ realmente, pero me parece que un sistema de consulta declarativa, en general, está relacionada con el modelo de especificación. En particular, implementar un sistema de consulta declarativa al componer objetos juntos en un entorno orientado a objetos. IIRC es similar a lo que hace LINQ, proporcionando una capa de azúcar sintáctica.

Si LINQ obsoletes por completo el patrón, no puedo decir. Tal vez hay casos de esquina que simplemente no se pueden expresar en LINQ?

0

LINQ:

var oldMans = Persons.Where(x => x.Sex == SexEnum.Masculine && x.Age > 60).ToList(); 

Especificación:

var oldMans = Persons.Where(x => IsOldManSpecification(x)).ToList(); 
  • la lógica de negocio es encapsuled en la especificación (con un nombre que revelan lo que es).
  • DRY: no repetir que LINQ sobre el código, sólo tiene que utilizar la especificación

me gusta usar la especificación cuando pienso que la regla es lo suficientemente importante como para ser explícita en el código, pero no pertenece a la entidad.

Ejemplo:

public class Customer 
{ 
    //... 

    public bool IsAbleToReceiveCredit(decimal creditValue) 
    { 
     var secureAge = this.Age > 18 && this.Age < 60; 
     var personalAssetsGreaterThanCreditValue = this.PersonalAssets.Sum(x => x.Value) > creditValue; 

     return secureAge && personalAssetsGreaterThanCreditValue; 
    } 
} 

¿Es de la Customer la responsabilidad para decidir si él es capaz de recibir algo de crédito?

Probablemente no.

Así que con la especificación puede eliminar esa lógica del Customer (nunca le perteneció). Puede crear algo como IsAbleToReceiveCreditSpecification y poner toda la lógica allí. Podemos ir más allá y combinar especificaciones, por ejemplo: puede crear un SecureAgeSpecification y un AssetsGreaterThanSpecification y usarlos para componer el IsAbleToReceiveCreditSpecification.

Así que no creo que LINQ reemplace la especificación. De hecho, mejora el patrón. Hay algunas implementaciones de Especificación que usan LINQ internamente con IQueriable<T>, con esto puede usar la especificación dentro de sus consultas ORM en el nivel de Repository/DataAcess.

Cuestiones relacionadas