Implement the Specification Pattern for Complex Business Rules

Implement the Specification Pattern for Complex Business Rules

Use the Specification pattern to encapsulate business rules and make them composable.

interface SpecificationInterface
{
    public function isSatisfiedBy($candidate): bool;
}

class UserIsAdultSpecification implements SpecificationInterface
{
    public function isSatisfiedBy($user): bool
    {
        return $user->age >= 18;
    }
}

class UserHasValidEmailSpecification implements SpecificationInterface
{
    public function isSatisfiedBy($user): bool
    {
        return filter_var($user->email, FILTER_VALIDATE_EMAIL) !== false;
    }
}

class AndSpecification implements SpecificationInterface
{
    private $specs;

    public function __construct(SpecificationInterface ...$specs)
    {
        $this->specs = $specs;
    }

    public function isSatisfiedBy($candidate): bool
    {
        foreach ($this->specs as $spec) {
            if (!$spec->isSatisfiedBy($candidate)) {
                return false;
            }
        }
        return true;
    }
}

// Usage
$validUserSpec = new AndSpecification(
    new UserIsAdultSpecification(),
    new UserHasValidEmailSpecification()
);

$user = new stdClass();
$user->age = 25;
$user->email = 'user@example.com';

if ($validUserSpec->isSatisfiedBy($user)) {
    echo "User is valid";
} else {
    echo "User is not valid";
}
← Back to Tips List