patternModeratepending
Specification pattern -- composable business rules
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.