面向领域开发(DDD)浅析

一、啥是DDD

程序其实是对现实业务的抽象。为了高效地满足复杂多变的业务需求,各种开发模型有很多。面向领域开发模型(Domain-Driven Design,简称DDD)就是其中之一,它旨在通过深入理解业务领域,将业务逻辑与软件设计紧密结合,以提高系统的可扩展性和可维护性。相关书籍有很多了,推荐一下《实现领域驱动设计》。本文是从实践经验出发,简单介绍面向领域开发模型的基本概念、核心组件以及如何应用的。

当然在介绍之前,我们可以先分析下其他的开发模型,看看和DDD的区别在哪里,以及为什么要用DDD。这里以常见的MVC(模型-视图-控制器)模型。当然MVC更侧重业务逻辑不复杂,和前端交互频繁的场景。在MVC中一般会存在controller->service -> dao的调用关系,如下图所示:

可以想见,当其他开发者在使用service和dao时,如果使用已有的方法来调用,那么可以复用;如果没有满足需求的方法,则会定义新的方法。而实际中调用的关系可能是更复杂的,在多个service、互相调用,就会出现n*m个调用关系,代码维护成本和可读性会变得很可怕。如果我们能控制业务的模型关系,仅提供针对性的入口给到上游,且修改时只调整模型逻辑,做到统一处理,是否可以控制调用的复杂度爆炸?下面我们就可以引入DDD了。

二、核心组件
  1. 领域模型(model):领域模型是DDD的核心,它是对业务领域中的实体、业务流程和事件的抽象。领域模型体现了业务领域的核心概念和逻辑。
  2. 聚合(aggregation):聚合定义了一组具有业务意义的实体和值对象的集合。聚合根一般是业务的入口点,负责保证聚合的一致性和完整性。
  3. 仓储(reposity):仓储可以理解MVC的dao,但是也有不同。它会封装对聚合根的读写操作,将聚合根与数据存储解耦。通过仓储提供的接口,领域层可以专注于业务逻辑的实现,而无需关心底层数据的存储细节。
  4. 应用服务(app):应用服务作为领域层对外的入口,提供给用户界面接口/外部服务等,负责协调领域对象还有模型来执行任务。
  5. 领域服务(domain service):有一些功能实现不能用单独的某个实体或值对象来表达时,或者这些行为需要跨越多个领域对象时,可以使用领域服务来封装。
  6. 领域事件(event):领域事件是DDD中用于实现领域对象之间解耦通信的一种机制。当一个领域对象的状态发生变化时,它可以发布一个或多个领域事件,后续业务可以订阅并处理这些事件。
三、开局一张图,开发全靠编

DDD模型我们简单上图来进行说明,在实践中可以参考。当然DDD只是一种编程思想,结构不是固定、僵化的,而是需要结合具体业务来灵活适配的。实践中可以参考下面的步骤来逐步抽象化模型,并定义相关组件,实现具体功能。

  1. 建立领域模型:与领域专家(一般是业务、产品,需求的提出方)讨论,理解业务领域后识别出关键的业务实体、值对象和服务,并定义它们关系和规则。
  2. 划分上下文:将业务领域划分为不同的上下文,每个上下文对应一个相对独立的子领域。这样的话能够逐步降低领域的复杂性,并专注于特定领域的实现。和原来的service不同点在于,提供的方法是固定业务场景的。
  3. 聚合和仓储:根据领域模型设计聚合和仓储,确保聚合根的一致性和完整性。仓储和原来的dao功能类似,但是触发点一定是领域模型生成的事件,或者其他模型定义结构。
  4. 领域服务:根据业务需求开发应用服务和领域服务,实现对上游业务的支持,在领域内部则协调不同组件的联动和协同。
  5. 处理事件:在关键的业务流程中,输出领域事件,基于事件来解决领域对象之间的松耦合通信。
  6. 迭代:随着业务的发展,不断对领域模型进行重构和迭代。
四、具体场景下的实现

需要说明的是,DDD模型会增加系统的复杂度,如果我们的服务主要是给前端提供接口,业务以检索、简单变更为主,那么MVC绝对是首选。仅在业务逻辑非常复杂时,才需要考虑使用DDD模型。举个🌰吧,一般我们认为交易流程是相对复杂的,那么可以定义下交易领域模型以及相关组件,并实现订单创建、交易、关单等业务。

  1. 建立领域模型:我们针对交易场景,其实可以再细分出不同的子领域,比如订单创建、交易达成、退款、关单等子领域。
  2. 划分上下文:我们以订单创建为例,在这个子领域中,上下文需要包含用户基本信息、订单基本信息,如果考虑到限额限次、风控策略等,还需要在上下文中定义出相关配置及适配器。
  3. 聚合和仓储:我们在操作数据库时,需要保证不同表的数据一致性等,可以在仓储中开启事务,操作库表。
  4. 领域服务:我们在创建订单时,需要有前置判断、创建单号、用户信息同步等,这里可以定义不同的领域模型和服务,来实现具体的节点功能。
  5. 处理事件:每个领域的节点在执行完成后,都会生成相应的事件,我们基于事件来调用仓促,执行具体的动作。或者通过消息对列通知下游业务。
  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值