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