领域驱动设计落地方案

一、现实问题

场景1
需求评审
产品大大:麻烦帮忙看一下xxx功能是什么逻辑,如果在xxx场景下能不能支持xxx
我:稍等我看一下代码的具体实现
一段时间后~
我:之前代码是这样写的,xxx xxx,好像不行,但xxx这样改,可以支持

场景2
线上异常数据出现,技术支持让排查问题
技术支持:入参xxx 出参xxx
我:怎么会呢,这个入参怎么会走这段流程,按理说不应该走这边嘛,然后输出xxx

二、问题原因

  1. 技术实现对于产品大大来说是个黑箱,产品大大一般对于产品本身的大局规划有深度理解,但对于产品功能细节是如何实现的可能模糊不清。所以在复杂场景下,特别是多条件叠加输入时,可能不知道代码流程会走
  2. 一般项目都由多人开发,开发人员对于经过多次版本迭代后的代码存在理解偏差

三、解决思路

对于业务模型进行抽象(DDD),对业务流程进行可视化输出。从而提高业务透明度,代码可维护性。

四、解决方案

第一阶段:战略设计

对业务进行领域战略建模,组织资深业务方、产品和技术进行思维碰撞,沟通目前产品功能和将来的规划。主要探讨产品是在干什么,解决什么问题,能给用户带来什么反馈(比如说交易系统核心就是买卖双方签订某种契约,买方如何付款,卖方如何履约。再比如说结算系统核心问题是根据订单决定给谁分帐,怎么分账)。
该阶段主要是统一目前的业务认知,咱们的系统到底在解决什么问题。
输出:

  1. 典型用户:产品服务对象。用一个人来描述一群人,就像用中间值描述一组数一样。减少修饰,避免误解。根据业务变化,迁移用户画像。
  2. 用户故事:以用户的角度去描述故事,这些故事就是产品使用的主要场景。

问题域的总结有三大好处:

  1. 统一思想。域模型的核心价值在于统一项目中各个相关方对问题的认识, 从而避免下游输出的结果和上游需要解决的问题脱节。


    在这里插入图片描述
  2. 清晰团队分工合作。产品可以划分为多个问题子域,由特定团队完成。
  3. 规划。产品往往是不断发展,但我们需解决的核心问题是在特定范围中的,所以提炼出核心问题域后,能减少变化对模型的冲击。
第二阶段:战术设计

对第一阶段总结问题域进行数据模型和业务流程设计。
领域实体类型设计
在第一阶段会输出很多的用户和用户故事,首先我们需按照优先级对故事进行排序,优先级高的就是核心场景。
接着我们需要在这些场景里面找出实体,也就是我们需要在大量的场景描述中找出对应的名词。比如说高中生张三下订单购买复习资料(举个例子,这段描述很简单),张三、订单和复习资料就是我们应该关系的实体,而高中生是形容词(是属性。这个也是业务方应该关心的,因为代表一类群体,能够帮助产品更好的聚焦用户),购买是行为(这是后边会讲到)。
有了实体之后,我们需要对实体进行总结抽象输出实体类型。比如说买家(张三)、订单(订单)和商品(复习资料)。
这个时候有同学可能就要问了,这不是我们常见的数据模型吗?确实领域模型需要被持久化,从而保存当前的状态。个人理解,怎么持久化只是一种方式,我们可以把实体直接持久化到数据库,也可以把实体拆分存到数据库中。比如说,一个人有姓名、身份证号、手机号、地址、买家身份等属性,我们可以把实体直接存到一个表中,也可以把实体拆分成多个表(user,address,role等)按照外键进行关联。
所以实体类型是对实体的抽象,数据模型是对实体当前状态的持久化。
在实体类型设计过程中,我们需要总结问题域中的实体,包括实体属性、关联关系和状态,从而抽象成实体类型。

实体类型能力抽象
有了实体类型之后,可以进行实体能力抽象(当然也可以在实体类型抽象时,顺带抽象实体能力)。能力的意思是实体能触发的行为,比如说人能看听闻触,这些就是基础能力。能力可以以实体类型方法的形式进行实现,也可以使用Manager层进行封装。只要遵循一个原则:实体和能力是一个高度自治的整体,实体状态的变更只能通过实体能力或者事件触发。不能将实体能力实现在各个业务流程中,这样不利于维护。
当然能力可以进行水平扩展,比如说带望远镜看,带听筒听。所以我们在进行实体能力抽象时主要关注基础能力,当然也要保留能力的扩展点(在简单场景中也可以不实现能力扩展点)。扩展点具体实现方式很多,比如说策略模式,SPI等,只要遵循一个原则:能力的消费方,不需要关注能力的具体实现,只关注能力的抽象。

业务流程设计
第一阶段中的用户故事需要抽象成业务场景,也就是一个个业务流程。
具体实现时,比如说下单场景,需要校验库存(商品能力),锁定库存(商品能力),生成订单(订单能力)。再比如说付款场景,需要扣减库存(商品能力),更新付款状态(订单能力),更新积分事件通知(积分能力)等等。
下图是对付款流程的举例,可能现实付款流程更复杂。

在这里插入图片描述

编码
编码过程是最简单的,有了之前的输出。我们只需要对实体和实体能力进行实现,具体可以以DDD充血模型进行实现,也可以自己封装高度自治的模块。然后进行业务流程的编排,编排可以用责任链模式。业务流程是根据基础能力进行编排的,是静态的,不存在在代码运行期进行动态编排,所以可以对业务流程进行可视化输出,以便将代码流程透明化输出给业务方。

最后,这是我和我的同事们在实际业务过程中的一些输出,可能有些主观的见解,欢迎指正。

参考:
《实现领域驱动设计》
https://mp.weixin.qq.com/s/LY9cT5P6WilLBKtXeT_p1g
https://developer.aliyun.com/article/6383

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358