The Specification Pattern is a domain-driven design (DDD) pattern where business rules and validation logic are encapsulated as reusable, composable boolean predicate objects. By chaining specifications using boolean combinators (and, or, not), software architectures maintain clean domain layers decoupled from database query generation.
This guide details specification interfaces, composite combinators, and translating specifications into SQL / JPA criteria queries.
Specification Composition:
[ IsEligibleForLoanSpec ] = [ HasValidCreditScoreSpec ]
.and( [ DebtToIncomeRatioSpec (< 43%) ] )
.and( [ HasNoRecentBankruptciesSpec ] )
export interface Specification<T> {
isSatisfiedBy(candidate: T): boolean;
and(other: Specification<T>): Specification<T>;
or(other: Specification<T>): Specification<T>;
not(): Specification<T>;
}
export abstract class CompositeSpecification<T> implements Specification<T> {
abstract isSatisfiedBy(candidate: T): boolean;
and(other: Specification<T>): Specification<T> {
return new AndSpecification(this, other);
}
or(other: Specification<T>): Specification<T> {
return new OrSpecification(this, other);
}
not(): Specification<T> {
return new NotSpecification(this);
}
}