开发人员在需求拿到之后,写代码前需要对项目进行需求分析和系统设计。一些业务逻辑和流程较复杂的项目,如何即能快速地抓住重点,清晰理解需求,又能设计出具体扩展性的系统架构呢?答案是使用领域驱动设计,以下是引用网上对此的一段描述:

领域驱动设计是一种针对大型复杂系统的领域建模与分析方法。它完全改变了传统软件开发工程师针对数据库进行的建模方法,从而将要解决的业务概念和业务规则转换为软件系统中的对象以及对象的属性与行为,通过合理运用面向对象的封装、继承和多态等设计要素,降低或隐藏整体系统的业务复杂性,并使得系统具有更好的扩展性,应对纷繁多变的现实业务问题。

重点:

  • 一种解决复杂系统的建模与分析方法
  • 将业务概念和规则转为对象和对象的属性行为
  • 通过封装、继承和多态降低业务复杂性

我们引入网上购物的例子来具体讲解如何使用DDD来指导分析业务和架构设计。

一. 需求梳理

需求梳理是第一步,主要的目的是理解业务需求,明确业务流程。采用的方式是通过画流程图去解构业务流程。

1. 去掉干扰项

为了更清晰了解业务功能,先去掉干扰项

  • 需求描述中的场外信息,如拿出手机,打开APP,连入网络等
  • 查询或不影响数据的操作,如浏览页面,打开商品页,点击查询
  • 外部系统操作,非当前系统功能,如用户注册,用户登陆,物流运输等

2. 抓住业务关键行为

解构业务关键行为,用简单的动名词句子来描述业务需求,这里可以是业务的大节点作为,但切记须是对数据产生影响的行为,如:

业务流程图

二. 领域结构设计

主要的目的是明确对象,对象服务能力以及对象的结构关系

1. 明确领域对象

通过主要行为确定领域对象,通常为业务描述中的名词,这种方式是以对象驱动行为的发生,这种是最常见的一种方式。对象是行为能力的拥有者,也是行为能力的参与者。如下订单,支付订单,确认收货等都是以订单作为对象的行为能力。
而另一种则是以行为驱动对象发生变化,对象只是行为能力的参与者,不是行为能力的拥有者。这是一个命令驱动模式,设计时将记录所有行为的发生,更强调可回溯性。如以交易记录做为对象去驱动账户余额或状态的变化,充值、消费等场景使用较多。

2. 识别领域服务

领域服务是领域对象拥有的行为能力,它必须是以现实业务的角度去识别,切勿以技术或数据的角度去分析。现实业务反映的是事物的规律变化,从而提取的规则天然会适配未来的变化,这也是领域驱动设计的精髓所在。实体是业务操作的承载者,行为命名代表着很强的领域概念,需要使用通用语言中的动词,应极力避免无法表达业务逻辑的命名。
服务的识别应保持服务功能的完整性,且职责的单一性,切分好服务的粒度,是可以对外使用的。

3. 划分领域边界

领域边界的划分就是划分功能的实现范围,行为能力的归属,对象间的解耦,明确系统结构关系。划分的标准也是以现实业务对象为参考点。
每个领域相对独立,各自的作用、结构与地位也不一样,有核心域,支撑域,通用域等。各域间明确通讯方式,根据不同的使用场景,有同步的也有异步的,并确认通讯的标准。

领域图

三. 领域模型设计

主要将上一图进行细化,明确各对象之间的关系和服务接口的设计,可以直接实现代码来呈现设计结果。这一步和以往的设计有所不同在于,它摒弃了针对数据库的建模设计,将开发设计人员的关注点从数据库层面转向了业务本身,将业务概念与规则直接转为系统对象与对象属性及行为上。这部分最大的不同点在于思考问题不再是按流程一个一个设计数据对象,等数据对象基本上设计完成后才能进行编码,而是从一个核心点开始,一步一步扩散,设计即编码,再逐步完善且不会影响结构,最终形成一个网。

1. 整理对象及关系属性

整理核心对象实体,完善重要属性。属性的数据类型可以是普通类型,也可以是自定义类型,一切以业务需求出发,这里需要厘清主对象与子对象的强弱关系。

2. 整理对象服务接口

服务接口的设计应该按第一节的分析,构建对象的行为能力,输入输出参数尽量以实体对象的形式出现。还需要考虑通用性和扩展性,共同的部分可提取统一处理,并对功能进行抽象封装。而不同的部分可根据实际情况进行合理设计。

  • 变化小的细节可通过使用属性标识区别,方便变化和扩展,切勿就具体对象使用硬编码的方式不易扩展
  • 大逻辑的大变化可使用多态的形式扩展,易于维护方便扩展

这一步完成之后,系统的整个大结构就出来了,再下来就是完善细化各部分逻辑了。

请关注我的公众号


barry的异想世界
20 声望3 粉丝