前言
最近浏览DDD相关文章,参加DDD主题演讲,感觉无法get到更多有用信息,想来是近半年的DDD理论学习和项目实践有了成果,是时候记录一波了。
本篇是战略设计篇。分享个人实践心得,不做百科式讲解。
战略设计目标
- 或者 “问什么需要战略设计”
- 达成业务共识
- 多角色参与。开发 产品 运营 市场 财务,角色越多越好,平级沟通,提高效率。
- 统一语言。不同角色在业务沟通时,请使用统一的“术语名词”,你觉得你理解了太片面,其他角色觉得你理解了才是真正理解了。
- 划分业务边界,识别上下文
就是划分模块或者微服务 - 识别领域对象,开始领域建模
- 实体和值对象
- 聚合与聚合根
- 用例、命令和事件
- 应用服务和领域服务
战略设计方法
- 事件风暴法
推荐,思维发散,各抒己见,但是实操起来并不容易,效益也并不如预期。 - 用例故事法
- 很推荐
- 业务专家和项目经理主导过程(也可能是同一个人...),代入客户/用户角色,按时序进行用例表述;产品作为辅助,其他成员随时提问和补充。
- 格式参考:什么人/系统(对什么)做什么(即用例名)+关键输入+关键输出+产生/影响+关键前置+关联与补充。
- 统一了用例表述后,从其中识别上下文和各个领域对象。
- 其他团队自创方式,只要能达到战略设计目标,都行。
案例
- 大致业务背景
- 以“锁汇换汇”业务为例。
- 客户先进行锁汇查询,系统返回锁汇结果。
- 客户如接受该锁汇汇率和计算结果,则可传入锁汇记录ID继续换汇下单。
- 系统检查下单条件通过,则完成下单动作,返回客户下单结果。
- 系统换汇订单成功和失败都会告知客户,订单成功客户可选则代发至目标收款人。
- 用例故事法
- 战略设计产出
- 换汇上下文
- 实体:客户锁汇订单、客户换汇订单
- 事件:锁汇成功事件、换汇订单完成/失败事件
- ...
- 客户信息上下文
- 客户信息
- 账户余额
- 付款上下文
- 付款
- 换汇上下文
战略设计心得
- 实体、值对象与聚合
- 某些对象会贯穿多个用例,所以需要被存储有了生命周期,即实体。
- 一般情况下,一个实体如有被查询维护(即CRUD)的需求,那么这个实体是聚合根。
- 推荐小聚合,不要偷懒把聚合设计得很大。一般关联性较强的一组用例可以使用一个聚合,但其中有很多CRUD需求的实体时,考虑小聚合。
- 有无被查询维护的需要,这点也可以用来区分实体和值对象,值对象一般不需要单独CRUD,所以很多时候,一个聚合中的值对象可以用一个实体字段json放置。比如换汇订单中的通道请求记录信息。
- 实践过程中,聚合的组织并不简单,初期可以弱化DDD聚合的概念,做到注意用例信息集和避免贫血模型就好。
- 识别事件
某个动作发生后,会对系统产生状态产生较大影响,这种动作应该拎出来作为“事件”。比如渠道下单成功/失败/交割成功。 - 上下文/微服务的识别
- 注意“二义性”,某个属性或对象在不同场景/用例中会出现不同表现意义时,那么请注意,这里一般可以划分上下文。比如换汇上下文的两个金额会关联出记账和付款所在上下文。
- 某个场景下,当不确定是否应该出现两个上下文时,那就先不要拆!