Spec<T> class sealed

The Specification Pattern: compose business rules as reusable, testable predicates.

A Spec represents a single business rule that an object either satisfies or doesn't. Instead of embedding validation logic directly in methods, specifications are first-class objects that can be created, combined, tested, and reused independently.

This pattern is ideal for:

  • Domain rules: Entity validation, filtering, and search criteria
  • Reusability: The same rule applies in multiple contexts without duplication
  • Testability: Each rule is isolated and easy to unit test
  • Composability: Combine simple rules into complex business logic
  • Readability: Express business intent clearly through method names

Compose specs using:

  • & / and — Both must be satisfied (AND logic)
  • | / or — At least one must be satisfied (OR logic)
  • ^ / xor — Exactly one must be satisfied, not both (XOR logic)
  • toNegated — Inverts the rule (NOT logic)

Creating a Spec:

/// Business rule: person is old enough to vote
class IsEligibleVoter extends Spec<Person> {
  @override
  bool isSatisfiedBy(Person person) => person.age >= 18;
}

/// Business rule: person has valid contact info
class HasValidEmail extends Spec<Person> {
  @override
  bool isSatisfiedBy(Person person) => person.email.contains('@');
}

Using a Spec:

// Single rule
final isVoter = IsEligibleVoter();
if (isVoter.isSatisfiedBy(person)) {
  registerToVote(person);
}

// Composed rules
final validVoter = IsEligibleVoter() & HasValidEmail();
final voters = people.where((p) => validVoter.isSatisfiedBy(p)).toList();

// Complex compositions
final canReceiveNewsletter = HasValidEmail() & (IsEligibleVoter() | HasOptedIn());
Annotations
  • @experimental

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

and(Spec<T> other) Spec<T>
Combines this spec with another using AND logic.
isSatisfiedBy(T candidate) bool
Checks if candidate satisfies this specification.
nand(Spec<T> other) Spec<T>
Combines this spec with another using NAND logic (NOT AND).
nor(Spec<T> other) Spec<T>
Combines this spec with another using NOR logic (NOT OR).
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
or(Spec<T> other) Spec<T>
Combines this spec with another using OR logic.
toNegated() Spec<T>
Creates a new spec that is the logical negation of this spec.
toString() String
A string representation of this object.
inherited
xnor(Spec<T> other) Spec<T>
Combines this spec with another using XNOR logic (NOT XOR / equivalence).
xor(Spec<T> other) Spec<T>
Combines this spec with another using XOR logic (exclusive OR).

Operators

operator &(Spec<T> other) Spec<T>
Combines this spec with another using AND logic (&).
operator ==(Object other) bool
The equality operator.
inherited
operator ^(Spec<T> other) Spec<T>
Combines this spec with another using XOR logic (^).
operator |(Spec<T> other) Spec<T>
Combines this spec with another using OR logic (|).