知识卡片
分层架构解耦的闭合层原则与依赖倒置
内容
[[层次化风格]]的解耦核心是”闭合层”原则:每一层都标记为闭合,意味着请求从一层移动到另一层时必须经过它正下方的层——例如源自表现层的请求必须先经过业务层,再经持久层,最后才能到达数据库层,不能跨层直接调用。这体现了分层架构的关键原则:每层只能与位于其下方的层发生耦合。对系统分层处理、按功能最终呈现做职责分离后,某一层内的改变通常不会影响其他层的组件——改变被隔离在该层内部,从而获得较低的耦合度;反之,如果设计中出现跨层调用(比如控制层绕过业务层,直接把持久层数据用于表现层呈现),架构看似分层,实际已经失去了分层的意义。经典分层设计前需要牢记两条原则:底层模块不应依赖高层模块,两者都应依赖抽象;抽象不应依赖细节,细节应依赖抽象——这正是达成高内聚低耦合目标的基础。这两条原则在领域驱动设计(DDD)的分层架构中体现得尤其具体:传统三层架构(用户界面层/业务逻辑层/数据访问层)常见的失败模式是代码集中在数据访问层(DAL),导致DAL和业务逻辑层(BLL)大量交叉,很多人索性去掉了BLL,结果三层架构名存实亡、耦合度反而很大。DDD分层架构分四层(用户接口层、应用层、领域层、基础设施层,领域层居中,其上是用户接口层和应用层,其下是基础设施层)——领域层或多或少需要使用基础设施层的能力,但基础设施层位于领域层下面,若让基础设施层向上直接引用领域层会增加耦合、违反分层原则。解决办法是”依赖倒置原则”:通过改变层间的依赖关系,让底层服务依赖高层组件提供的接口(而不是高层依赖底层的具体实现)——具体做法是把基础设施层重新放到所有层的最上方(在依赖关系图上倒置过来),这样领域层定义接口、基础设施层实现并依赖这些接口,领域层本身不再向下依赖具体的基础设施实现,从而在保留基础设施能力的同时,避免了”底层反向依赖上层”这个违反分层原则的耦合。
结构图:
flowchart TD
A[用户接口层] --> D[领域层]
B[应用层] --> D
D -.定义接口.-> C["基础设施层<br/>(依赖倒置:实现领域层定义的接口,而非领域层直接依赖它)"]