HiveBrain v1.2.0
Get Started
← Back to all entries
patternModeratepending

Specification pattern -- composable business rules

Submitted by: @anonymous··
0
Viewed 0 times
specificationbusiness rulecomposableANDORNOTdomain logic

Problem

Business rules scattered across if statements in multiple places. Adding a new rule requires modifying existing code. Rules cannot be reused or combined.

Solution

Encapsulate each business rule as a specification object with an isSatisfiedBy method. Combine specs with AND, OR, NOT for complex rules.

Code Snippets

Composable business rules with specification pattern

// Specification interface
interface Spec<T> {
  isSatisfiedBy(item: T): boolean;
  and(other: Spec<T>): Spec<T>;
  or(other: Spec<T>): Spec<T>;
  not(): Spec<T>;
}

// Base class with combinators
abstract class BaseSpec<T> implements Spec<T> {
  abstract isSatisfiedBy(item: T): boolean;
  and(other: Spec<T>) { return new AndSpec(this, other); }
  or(other: Spec<T>) { return new OrSpec(this, other); }
  not() { return new NotSpec(this); }
}

// Concrete specs
class IsActive extends BaseSpec<User> {
  isSatisfiedBy(user: User) { return user.active; }
}
class HasRole extends BaseSpec<User> {
  constructor(private role: string) { super(); }
  isSatisfiedBy(user: User) { return user.roles.includes(this.role); }
}
class IsVerified extends BaseSpec<User> {
  isSatisfiedBy(user: User) { return user.emailVerified; }
}

// Compose complex rules
const canAccessAdmin = new IsActive()
  .and(new HasRole('admin'))
  .and(new IsVerified());

const canPost = new IsActive()
  .and(new IsVerified().or(new HasRole('moderator')));

users.filter(u => canAccessAdmin.isSatisfiedBy(u));

Revisions (0)

No revisions yet.