原则:
- 每层只能和位于其下方的层发生耦合。
目的:
- 有效降低层与层之间的依赖。
分类:
- 严格分层架构:某层只能与位于其直接下方的层发生耦合
- 松散分层架构:允许某层与它的任意下方层发生耦合。
传统三层架构
-
表示层(web)
-
业务逻辑层(business/service)
-
数据访问层(dao)
缺点:
- 类的职责不易划分
- 类的依赖关系混乱
- 业务处理逻辑和技术处理逻辑混合在一起
- 一个业务领域的动作分散在多处,不易复用,迭代成本高。
- 事务控制范围太大
DDD分层架构:
目的
- 将技术复杂度和业务复杂度分离,让领域层负责业务复杂度,让应用层和基础设施层负责技术复杂度。
DDD传统四层架构
用户接口层(User Interface)
- 负责向用户显示信息和解释用户指令,这里的用户可能是用户,也可能是外界其它系统。
应用层(Application)
- 应用层是很薄的一层,理论上不应该有业务规则或逻辑,主要面向用例,通过对领域层对象的编排,实现了用例。
- 应用层除了负责调用领域层和基础设施层,还需要协调并发控制、事务控制、权限控制等技术事项。
领用层(Domain)
- 领域层的作用是实现企业核心业务逻辑,领域层主要体现领域模型的业务能力,它用来表达业务概念、业务状态和业务规则,与具体的实现技术无关。
基础设施层(Infrastructure)
- 基础层是贯穿所有层的,它的作用就是为其它各层提供通用的技术和基础服务,包括第三方工具、消息中间件、缓存以及数据库持久化等。
优化后的四层架构
传统四层架构的问题:
-
基础设施层放入底层是存在缺点的,领域层依赖于基础设施层,这对DDD的核心层-领域层的内聚性会产生影响。
四层架构的优化:
依赖倒置原则(DIP):
-
高层模块不应该依赖于底层模块,两者都应该依赖于抽象。
-
抽象不应该依赖于实现细节,实现细节应该依赖于接口。
-
按照DIP的原则,领域层和基础设施层都只依赖于由领域模型所定义的抽象接口,这样领域层就可以不再依赖于基础设施层,而基础设施层通过注入抽象接口的实现就完成了对领域层的解耦。
按照依赖倒置原则(DIP),各层的内容如下:
用户接口层(User Interface)
- 接口实现类(controller、rpcServiceImpl)
- 消息监听类(listener)
应用层(Application)
- 调用领域层的实体对象完成一个业务。
- 调用repository保存数据。
领域层(Domain)
- entity
- value object
- domain service
- event publisher/subscriber
- repository interface
- adapter interface
基础设施层(Infrastructure)
- repository
- DDD分层架构的数据库等基础资源访问,采用了仓储(Repository)设计模式,通过依赖倒置实现各层对基础资源的解耦。
仓储又分为两部分:仓储接口和仓储实现。仓储接口放在领域层中,仓储实现放在基础层。 - mq(发消息)
- cache
- 中间件
- adapter
传统三层架构和DDD四层架构的比较:
-
DDD分层架构对三层架构的业务逻辑层进行了更清晰的划分,改善了三层架构核心业务逻辑混乱,代码改动相互影响大的情况。
-
DDD分层架构将业务逻辑层的服务拆分到了应用层和领域层。应用层快速响应前端的变化,领域层实现领域模型的能力。
说明:
- DDD代码分层架构中,由于用户界面层和应用层通常都需要与基础设施层打交道,故很多系统都是采用松散分层架构。
拓展
-
六边型架构
-
CQRS架构