业务|如何从0到1实践DDD( 三 )


  1. 增值运营服务子域:核心域,是我们业务主要竞争力。从业务上来讲,我们的核心是通过提供业务中IoT设备上的增值运营服务
  2. 增值运营产品子域:支撑域,这里主要是我们提供增值运营产品,如电子海报、互动海报等
  3. 生效场景子域:支撑域,业务中增值运营产品有不同生效场景,这里统一进行管理
  4. 准入子域:支撑域,现主要是业务中对使用者的一些限制规则
  5. 权限管理子域:支撑域,基于角色来管理使用者的权限
  6. 商户信息子域:支撑域,提供商户的信息
  7. IoT设备信息子域:支撑域,提供IoT设备的信息
  8. 风险识别子域:通用域,识别业务中一些安全风险,如不合规的UGC素材等。这部分是业界常见问题,可以使用通用方案来解决,实际上我们也是接入TEG的能力来实现
其中我们系统中的商户信息依赖了微信支付商户账号信息和IoT设备铺设服务信息,这里使用防腐层进行隔离,将外部的商户信息“翻译”为我们业务中的商户信息。三、如何实现DDD之战术建模梳理清楚上下文之间的关系后,我们基本了解业务的概貌,接下来需要细化上下文,进一步完善我们的模型。这里也需要用到DDD的一些基本概念。
3. 基本概念1)实体、值对象
实体和值对象是组成领域模型的基础单元。当一个对象由其标识(而不是属性)区分时,这种对象称为实体。如在校园教务系统中,每个账户是对应着一个学生,根据学号来唯一标识,可以认为是一个实体。传统的数据建模大多是根据数据库范式设计的,每一个数据库表对应一个实体,每一个实体的属性值用单独的一列来存储,一个实体主表会对应 N 个实体从表。
与其不同,DDD 是先构建领域模型,再将业务对象映射为持久化对象。这可能导致DDD建立出来的实体,映射到具体数据库表时,可能是1对多,多对1的关系。
如一个账户实体,有它的基本信息和权限角色信息,可能就对应了2个持久化对象。另一方面,有时候为了某些查询场景的方便,会把教师账户、学生账户等对应成一个持久化对象,就成了多对1。
通过对象属性值来识别的对象,则可以认为是一个值对象。如地址信息{“省”: “广东省”,”市”:”深圳市”},我们是通过它的属性来区分出不同的地址。值对象实际上是想把一些不变的属性组合起来,减少系统的复杂性。在设计值对象的时候,需要满足以下的特性:
  1. 值对象相等性:可以通过对其属性的比较,来区分不同的值对象
  2. 不变性:需要保证值对象创建后就不能被修改,即不允许外部再修改其属性
  3. 可替换性:值对象是一个整体,当其描述的对象有变化时,需要用一个新的值对象来替换对于值对象,由于其具有不变性,且是通过属性来判断相等的,在设计对应的数据库持久化对象时,可以将其以JSON形式存储在数据库表的某一字段中
业务|如何从0到1实践DDD
文章插图
2)聚合、聚合根
在 DDD 中,实体和值对象是基础的领域对象。实体一般对应业务对象,它具有业务属性和业务行为;而值对象主要是属性集合,对实体的状态和特征进行描述。但是我们的一个业务流程中,一般会同时涉及多个实体、值对象的操作,这里业务逻辑紧密的实体和值对象便组合成一个聚合。
从数据层面来看,同个聚合内的数据需要保持强一致性。
每一个聚合有一个聚合根实体,设置聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间数据不一致性的问题。聚合根可以看成是聚合的管理者,或是说handle。对内其协调实体和值对象完成业务逻辑。对外则提供通过聚合ID供其他聚合关联引用,屏蔽外部对内部实体的直接访问和修改。