关注点分离是什么
关注点分离(Separation of Concerns)指把系统按不同的关注点切分——业务规则、持久化、展示、安全、可观测等,使每个部分可以被单独理解、单独修改、单独测试。它是分层、模块化、面向切面编程与中间件机制的共同基础:Dijkstra 在 1974 年关于结构化编程的论述中就强调过相关思想。检验是否做到位的方法很直接:修改某一个关注点时,改动是否收敛在少数模块内。
基本信息
| 思想来源 | Edsger Dijkstra 在结构化编程相关论述中提出(1974) |
|---|---|
| 落地手段 | 分层、模块化、横切关注点抽离(AOP、中间件、装饰器) |
| 检验标准 | 改动某一关注点时影响范围是否收敛在少数模块 |
| 常见误区 | 按技术层分离,却把同一业务规则拆散到多个层 |
| 权衡原则 | 分离带来的接口与协调成本,要小于它降低的理解成本 |
典型使用场景
- 分层设计:接口层只做协议转换与校验,业务规则集中在领域层
- 横切能力抽离:日志、鉴权、限流、埋点由中间件统一处理
- 测试隔离:业务规则可在不启动数据库与 Web 容器的情况下单测
- 替换实现:持久化或消息实现更换时,业务代码基本不动
- 并行协作:不同关注点由不同人负责,接口约定清楚后互不阻塞
- 故障定位:问题按关注点收窄范围,例如先排除展示层再看业务规则
关注点与常见承载
| 关注点 | 承载方式 | 分离不到位的表现 |
|---|---|---|
| 业务规则 | 领域模型与用例 | 规则散落在接口层与存储过程里 |
| 持久化 | 仓储接口与 ORM 映射 | SQL 拼在业务逻辑中,换库要改业务代码 |
| 展示 | 视图模板与 DTO | 返回结构与数据库表结构完全耦合 |
| 安全 | 过滤器、中间件与策略 | 每个接口各自写一遍鉴权 |
| 可观测 | 埋点、日志与追踪切面 | 日志格式各异,无法按统一维度检索 |
依赖方向示意
依赖方向示意
# 接口层 → 应用层 → 领域层:依赖单向向内
# 基础设施(数据库、消息、外部接口)实现领域定义的口径接口
# 允许:infrastructure → domain(实现接口)
# 禁止:domain → infrastructure(领域层引入框架与驱动依赖)
# 检查:用依赖规则工具在构建期扫描包引用,发现环或反向依赖即失败按技术层分离容易做过头:同一业务规则被拆到接口层、服务层与存储过程三处,改一次要动三个地方,反而破坏了「按变化原因分组」的初衷。
横切关注点适合抽到中间件或切面里,但抽离层次要克制:一层切面解决不了的事,硬塞进去只会让调用链更难追踪。