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.
Estoy enfrentando esta situación exacta en este momento, por lo que esta pregunta es de gran interés para mí. –