实现领域驱动设计
实现领域驱动设计
写代码非常简单,但是写简单的代码却非常难
随着应用程序的变化,有时候,为了节省开发时间会违反一些本应遵守的规则,使得代码变得复杂且难以维护.短期来看确实节省了开发时间,但是后期可能需要花费更多的时间为之前的偷懒而买单.无法对原有的代码进行维护,导致大量的逻辑都需要进行重写.
什么是领域驱动设计?
领域驱动设计(DDD)是一种将实现与持续进化的模型连接在一起来满足复杂需求的软件开发方法.
DDD适用于复杂领域或较大规模的系统,而不是简单的CRUD程序.它着重于核心领域逻辑,而不是基础架构.这样有助于构建一个灵活,模块化,可维护的代码库.
核心构建组成
DDD的关注点在领域层和应用层上,而展现层和基础设施层则视为细节(这个词原文太抽象,自己体会吧),业务层不应依赖它们.
这并不意味着展现层和基础设施层不重要.它们非常重要,但UI框架 和 数据库提供程序 需要你自己定义规则和总结最佳实践.这些不在DDD的讨论范围中.
本节将介绍领域层和应用层的基本构建组件.
领域层构建组成
- 实体(Entity): 实体是种领域对象,它有自己的属性(状态,数据)和执行业务逻辑的方法.实体由唯一标识符(Id)表示,不同ID的两个实体被视为不同的实体.
- 值对象(Value Object): 值对象是另外一种类型的领域对象,使用值对象的属性来判断两个值对象是否相同,而非使用ID判断.如果两个值对象的属性值全部相同就被视为同一对象.值对象通常是不可变的,大多数情况下它比实体简单.
- 聚合(Aggregate) 和 聚合根(Aggregate Root): 聚合是由聚合根包裹在一起的一组对象(实体和值对象).聚合根是一种具有特定职责的实体.
- 仓储(Repository) (接口): 仓储是被领域层或应用层调用的数据库持久化接口.它隐藏了DBMS的复杂性,领域层中只定义仓储接口,而非实现.
- 领域服务(Domain Service): 领域服务是一种无状态的服务,它依赖多个聚合(实体)或外部服务来实现该领域的核心业务逻辑.
规约(Specification): 规约是一种强命名,可重用,可组合,可测试的实体过滤器. - 领域事件(Domain Event): 领域事件是当领域某个事件发生时,通知其它领域服务的方式,为了解耦领域服务间的依赖.
应用层构建组成
- 应用服务(Application Service): 应用服务是为实现用例的无状态服务.展现层调用应用服务获取DTO.应用服务调用多个领域服务实现用例.用例通常被视为一个工作单元.
- 数据传输对象(DTO): DTO是一个不含业务逻辑的简单对象,用于应用服务层与展现层间的数据传输.
- 工作单元(UOW): 工作单元是事务的原子操作.UOW内所有操作,当成功时全部提交,失败时全部回滚.