Specification
Encapsula reglas de negocio que devuelven booleanos en objetos componibles (AND, OR, NOT).
Contexto
Reglas de elegibilidad complejas: "es cliente premium AND vive en EU AND ha hecho >5 compras este año".
Problema
Repartir esas reglas con ifs a lo largo del código las vuelve incoherentes.
Solución
Cada regla es una Specification<T> con IsSatisfiedBy(T). Se combinan con operadores.
#Ejemplo en C#
public abstract class Spec<T>
{
public abstract bool IsSatisfiedBy(T candidate);
public Spec<T> And(Spec<T> other) => new AndSpec<T>(this, other);
public Spec<T> Or(Spec<T> other) => new OrSpec<T>(this, other);
}
internal class AndSpec<T> : Spec<T>
{
private readonly Spec<T> _a, _b;
public AndSpec(Spec<T> a, Spec<T> b) { _a = a; _b = b; }
public override bool IsSatisfiedBy(T c) => _a.IsSatisfiedBy(c) && _b.IsSatisfiedBy(c);
}
public class IsPremium : Spec<Customer>
{ public override bool IsSatisfiedBy(Customer c) => c.Tier == "premium"; }
public class LivesInEU : Spec<Customer>
{ public override bool IsSatisfiedBy(Customer c) => EuCountries.Contains(c.Country); }
var eligible = new IsPremium().And(new LivesInEU());
bool ok = eligible.IsSatisfiedBy(customer);Tradeoffs
| Pro | Contra |
|---|---|
| Reglas reusables y testeables | Más clases por regla |
| Encaja con DDD | Difícil traducir a SQL si lo usas como filtro de repositorios |
#extra #ddd #rules