ddd中的领域服务与应用服务
领域服务和应用服务的区别
应用层和领域层:
- 应用层(Application):负责展现层与领域层之间的协调,协调业务对象来执行特定的应用程序任务。它不包含业务逻辑。
- 领域层(Domain):负责表达业务概念,业务状态信息以及业务规则,是业务软件的核心。
理解领域服务和应用服务:
服务:行为的抽象
应用服务:对应具体的操作,主要关注从开始到结束的步骤
领域服务:对应用行为的细化,具体到每一个环节
所以可以认为,应用服务就是协调多个领域服务来完成一件事
一个业务动作往往需要多个实体协同完成(实体只完成个体业务),此时就需要构建领域服务完成相关的实体业务逻辑; 有时候甚至需要跨多个聚合共同完成业务逻辑,此时就需要构建应用服务
所以综合来看应用服务是用来表述应用行为,而领域服务用来表述领域行为。
那怎么理解应用行为和领域行为呢,应用行为描述了一个具体操作从开始到结束的每一个环节,而领域行为是对应用行为的细化,用来处理具体的某一个环节。比如,我们手机购物,从购物车结算这一场景来举例,这就是一个应用行为。而这个应用行为又主要包括金额计算、支付、生成订单,这些子环节就可以理解为一个领域行为。
领域服务
领域层就是较“胖”的一层,因为它实现了全部业务逻辑并且通过各种校验手段保证业务正确性。而什么是业务逻辑呢?业务流程、业务策略、业务规则、完整性约束等。
当领域中的某个操作过程或转换过程不是实体或值对象的职责时,我们便应该将该操作放在一个单独的接口中,即领域服务。请确保该服务和通用语言时一致的;并且保证它是无状态的。
根据这句话我们有几个问题需要理清:
- 什么时候使用领域服务?
- 领域服务无状态怎么理解?
领域服务是用来协调领域对象完成某个操作,用来处理业务逻辑的,它本身是一个行为,所以是无状态的。状态由领域对象(具有状态和行为)保存。
上面也说了,领域对象是具有状态和行为的。那就是说我们也可以在实体或值对象来处理业务逻辑。那我们该如何取舍呢?
一般来说,在下面的几种情况下,我们可以使用领域服务:
- 执行一个显著的业务操作过程
- 对领域对象进行转换
- 以多个领域对象为输入,返回一个值对象。
应用服务
应用服务是用来表达用例和用户故事(User Story)的主要手段。
应用层通过应用服务接口来暴露系统的全部功能。在应用服务的实现中,它负责编排和转发,它将要实现的功能委托给一个或多个领域对象来实现,它本身只负责处理业务用例的执行顺序以及结果的拼装。通过这样一种方式,它隐藏了领域层的复杂性及其内部实现机制。
应用层相对来说是较“薄”的一层,除了定义应用服务之外,在该层我们可以进行安全认证,权限校验,持久化事务控制,或者向其他系统发生基于事件的消息通知,另外还可以用于创建邮件以发送给客户等。
应用层作为展现层与领域层的桥梁。展现层使用VO(视图模型)进行界面展示,与应用层通过DTO(数据传输对象)进行数据交互,从而达到展现层与DO(领域对象)解耦的目的
总结
- 服务是行为的抽象。
- 应用服务通过委托领域对象和领域服务来表达用例和用户故事。
- 领域对象(实体和值对象)负责单一操作。
- 领域服务用于协调多个领域对象共同完成某个业务操作。
- 应用服务不处理业务逻辑,领域服务处理业务逻辑。