principleModeratepending
Principle: Separate mechanism from policy
Viewed 0 times
mechanismpolicyseparation of concernsunix philosophyreusability
Problem
Code that mixes 'how to do something' with 'what to do' is hard to reuse, test, and modify.
Solution
Separate the mechanism (how) from the policy (what/when):
Examples from Unix:
The mechanism should be general-purpose. The policy should be configurable.
# BAD: Mechanism and policy mixed
class UserService:
def create_user(self, name, email):
# Policy: validation rules
if len(name) < 2:
raise ValueError('Name too short')
if '@' not in email:
raise ValueError('Invalid email')
# Mechanism: storage
user = User(name=name, email=email)
self.db.save(user)
# Policy: side effects
self.send_welcome_email(user)
self.notify_admin(user)
return user
# GOOD: Separated
class UserRepository: # Mechanism: how to store
def save(self, user: User) -> User: ...
class UserValidator: # Policy: validation rules
def validate(self, name, email) -> list[str]: ...
class UserService: # Policy: orchestration
def __init__(self, repo, validator, events):
self.repo = repo
self.validator = validator
self.events = events
def create_user(self, name, email):
errors = self.validator.validate(name, email)
if errors:
raise ValidationError(errors)
user = self.repo.save(User(name=name, email=email))
self.events.emit('user_created', user)
return userExamples from Unix:
find(mechanism: traverse filesystem) +-exec(policy: what to do)sort(mechanism: sorting) + input from any source (policy: what to sort)cron(mechanism: scheduling) + crontab entries (policy: what/when to run)
The mechanism should be general-purpose. The policy should be configurable.
Why
When mechanism and policy are separated, you can change business rules without touching infrastructure code, and reuse mechanisms across different policies.
Context
Designing systems and APIs with clear boundaries
Revisions (0)
No revisions yet.