Separation of concerns organizes software into distinct parts, each responsible for a specific concern such as data access, business logic, or user interface. The aim is to let each part change with less disruption to the rest of the system. section 9.1 section 9.1.1
From a grab bag to focused services
An OrderTools class that calculates prices and sends confirmation emails has low cohesion: unrelated responsibilities share one home. Splitting it into PricingService and NotificationService gives each class a focused purpose and reduces the reasoning required for change. section 9.1.1
Good separation balances high cohesion with loose coupling. Keep related logic together inside a component, while limiting the interactions between components, layers, and classes. Fewer dependencies reduce the number of places that must change when an interface or implementation evolves. section 9.1.1
Apply the principle when designing boundaries:
- Isolate business rules from frameworks, databases, and user interfaces so technical replacements do not require rewriting core logic. section 9.1
- Expose only necessary entry points and pass domain-relevant information rather than configuration values, internal identifiers, or database keys. section 9.4.1
- Translate technical exceptions into meaningful domain-level errors and use clear response models that reveal each field's purpose. section 9.4.1
- Protect public boundaries with automated tests that simulate client behavior and detect breaking changes before release. section 9.4.1
The same movement appears at multiple scales: entangled code becomes layered, then modular, and eventually organized around a protected domain model. Separation is not a rigid architecture; it is a recurring decision about where responsibilities and dependencies belong. section 9.1 section 9.5





















