简介: DDD是一套方法论,实践能否成功,不仅仅是个技术问题,更是执行贯彻实施的问题。本文将就DDD的基本概念和DDD的实施进行分享。

作者 | 侧帽
来源 | 阿里技术公众号

前言

供应链商品域DDD实践时间不长,在实践过程也碰到了不少问题,有些找到了答案,有些还是在探索中。最近很荣幸受邀在供应链服务与创新团队做了一次分享,也想在这里把一些经验和想法分享给大家,借此抛砖引玉。

DDD是一套方法论,实践能否成功,我觉得不仅仅是个技术问题,更是执行贯彻实施的问题。

本文内容主要有两部分,DDD基本概念和DDD实施。基本概念包括通用语言、分层架构、DDD要素、边界上下文,DDD实施包括领域知识提取方法、思考方式的转变,在其中会穿插一些商品案例。

一 软件复杂性是什么?

在开始DDD前,我们应该先回答的一个问题,我们为什么需要DDD?DDD是复杂软件应对之道,所以我们来一起看看,软件的复杂度到底在哪里?

在阿里两年,我感受很深的一个点是,我们不能持续交付不断演进的复杂软件,所以有1.0、2.0、3.0很多的版本,1.0搞不下去了,开始2.0,2.0也搞不下去了,开始3.0,不断循环。

阿里体系复杂度我看来是理解力、不可预测、协作力挑战三个方面。

1 理解力挑战

  • 需求规模庞大,业务数量和类型不断增多,业务相互耦合,不同业务相互影响。供应链有20多个行业,经销、代销、一盘货等各种商业模式,有跨境进口、国内业务、国际化业务,这些纵横导致系统复杂度大幅提升。
  • 业务系统多,边界划分不清,系统间依赖复杂。如供应链商品和共享SELL、AIC和IPM,一直都有边界问题,一个大项目过来,边界问题就得讨论上好几天。
  • 系统结构复杂,因为应对高并发、高稳定性等,功能性代码与非功能性代码混合,如业务代码混杂着各种兜底逻辑、灰度逻辑、重试等等,100行代码,可能业务代码不到30行。

2 不可预测性挑战

  • 商业环境复杂多变,商业流程、规则多变。商业环境变化快,今年国际化、智能商业路由、考拉融合一下子都来了,在设计上很难前期都规划好。
  • 变化不可预测,软件系统变化也不可预测,带来设计挑战。

3 协作力挑战

  • 大部分需求横跨多个团队,需求传递低效,需要反复沟通,方案产出效率低。
  • 团队角色多,业务概念多,没有统一语言,大家理解容易出现偏差。

二 Why DDD?

DDD设计合适的领域模型来映射现实中的业务,来有效地解决领域中的核心的复杂问题,是对OOAD的扩展和延伸,其解决之道:

  • 分而治之,控制规模。
  • 关注点分离,应对理解力挑战,领域模型与存储模型分离,业务复杂度与技术复杂度分离。
  • 分层架构、分离核心,保持结构清晰,应对不可预测性挑战。
  • 统一语言,应对协作力挑战。

三 DDD核心

1 通用语言

通用语言是提炼领域知识的产出物,获得统一语言就是需求分析的过程,也是团队中各个角色就系统目标、范围与具体功能达成一致的过程。

领域语言团队专有,负责解释和维护,相同名称概念,跨出这个团队,理解可以完全不一样。

领域专家、产品经理、开发人员共同的语言,这种语言是将领域专家和技术人员联系在一起的纽带。

在各种文档和平时沟通中,保持概念统一,特别提一下,做一个中文对照, 把概念和代码连接起来,在代码做到概念名称统一,减少混淆。

通用语言价值:

  • 定义公共术语,减少概念混淆。
  • 沟通达成一致的提前,消除歧义和理解偏差,提升需求和知识消化的效率。
  • 概念和代码的统一语言,连接概念和实现。

2 分层架构

DDD第二个核心是分层架构,分离模型。优秀的架构应该是什么样子?关注点是分离的,可以分而治之,可测试性好。

一个人同时要做多件事情的时候,难免手忙脚乱。代码也一样,一段代码要处理各种事情的时候,也会乱成一团,所以我们要分解开来,各个击破。

商品域领域模型,在分层架构中的位置,如下:

  • CQRS模式:领域模型在应用层下面,command才走领域模型;查询和搜索服务不走。
  • tunnel层,对接db、外部数据资源访问,领域和模型解耦,类似DAO。
  • 外部通过SPI和模型交互,六边形的adapter模式。

3 DDD要素

1)实体:有id,有生命周期和状态。有属性,有行为。外部事件会触发他的行为和状态变化。

实体和vo的区分,vo属性不能修改,使用final修饰。vo为表达模型减负,如商品有100多个属性,铺平开不能体现结构化,不能体现分层分类,将相似描述性属性分组封装成一个个vo。

2)为什么需要service,如批量操作多个实体、跨实体操作,如商品复制,转账。

商品域的工程架构:

  • serivce职责是:实体创建,持久化,跨实体操作等。
  • 不同层使用不同数据对象,tunnel使用dataobjects,面向存储,需要和实体相互转换。
  • 实体间有关系,可以动态加载关联对象;dataobjects只有数据,没有行为,一般也不会有关系。

4 边界上下文

  • 边界 = 域或子域。
  • 领域对象在领域内才有确切的含义。出了这个边界,不能确保还是这个含义,如苹果。
  • 语言是有上下文的。
  • 在不同的上下文中,职责和任务不一样。人有多个角色,在家里是爸爸、在公司是小二,职责和任务不一样。

上下文映射:

  • 有了边界,那么领域如何输出价值呢?一个完全封闭的系统没有任何价值。
  • 常用的方式有:共享内核,防腐层等。防腐层:商品上游提供spi,spi不是直接对外开放领域模型,建立一层开放视图。采购域建立防腐层,收口商品的变更对本域影响。

四 DDD实施

1 DDD实施的挑战

  • 识别和提炼领域知识,并体现在模型代码上,强调一次“并体现在模型代码上”!
  • 防腐,保持模型不断演进,需要持续投入,保证DDD贯彻执行。
  • 人的转变,开发思考方式的转变。

2 什么是领域知识?

领域知识有分层分类,平台通用商业规则,是领域模型主要输入,商家个性化不能下沉到领域模型层。

3 领域知识提炼,需求和链路5W1H分析法

两阶段分析:用户故事、链路和边界分析。

  • 前3W描写用户故事,用户要什么,为什么要?举个例子,我作为采购小二,需要商品库存为0自动下架,因为有超卖风险,客户会投诉。
  • 后面的When、Where、How是链路和边界分析,触发的条件是什么,要实现这个功能需要哪些域参与进来,分别提供什么能力?

通过这个分析,获取用户需求,和全链路分工。

4 领域知识提炼,结构化分析

  • APP层至上而下过程分析,模型层自下而上分析相结合。
  • 能力下沉保持模型不断演进,能力下沉标准:复用、内聚。

5 思考方式的转变

领域驱动,在模型阶段不会关注数据设计、不会关注存储、不会关注消息怎么发,业务和技术视角关注点做了分离。

五 商品域实践相关

商品域工程架构:

最后,保持模型不断演进!!!

商品域模型更新readme,保持模型不断演进。否则会APP层会越来越大,模型层越来越小,最后头重脚轻,领域坍塌了。

原文链接
本文为阿里云原创内容,未经允许不得转载。

供应链商品域DDD实践的更多相关文章

  1. DDD实践反思

    某大型互联网公司于2019年开始在XX中台财务域进行DDD实践.事后回顾,整体并没有达到预期的效果,个人也做了很多的反思和总结,形成此文. 1. 背景 为什么当时要实践DDD?其中的缘由比较复杂,可以 ...

  2. DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...

  3. DDD实践切入点(二)

    最近发现下面关于上下文的理解有些问题,不太好改,暂时先不改了 承前:大型系统的支撑,应用系统开发思想的变迁,DDD实践切入点(一) 从大比例结构入手已经开始了系统的建设,大家都知道需求是会不断变化不断 ...

  4. DDD实践2

    DDD实践切入点(二) 承前:大型系统的支撑,应用系统开发思想的变迁,DDD实践切入点(一) 从大比例结构入手已经开始了系统的建设,大家都知道需求是会不断变化不断深入的,刚开始自然是模糊的大比例结构对 ...

  5. DDD实践(一)

    DDD实践切入点(一) 前两篇:大型系统的支撑,应用系统开发思想的变迁 之前大致说了使用DDD的前期准备,现在可以真正开始实践了,以我刚刚结束的一个简单的经典DDD方式的项目为例子,当然由于比较简单, ...

  6. 领域驱动设计(DDD)实践之路(一)

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/gk-Hb84Dt7JqBRVkMqM7Eg  作者:张文博 领域驱动设计(Domain Dr ...

  7. DDD实践切入点(一)

    前两篇:大型系统的支撑,应用系统开发思想的变迁 之前大致说了使用DDD的前期准备,现在可以真正开始实践了,以我刚刚结束的一个简单的经典DDD方式的项目为例子,当然由于比较简单,所以很多时候会脱离它来介 ...

  8. [.NET领域驱动设计实战系列]专题七:DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己的订单状态看到店家已经发货.从上面的业务逻辑可以看出,当用户 ...

  9. DDD实践

    一. 虽然招聘是主旋律,但技术还是得不断的突破.在.net core的实践中,一开始就瞄准了DDD.需要特别感谢https://github.com/EduardoPires/EquinoxProje ...

  10. 在单体应用的一些DDD实践经验

    阅读此文需要一定的DDD基础,如果你是第一次接触DDD读者,建议先去阅读一些DDD相关的书籍或者文章之后再来阅读本文. 背景 自从我在团队中推行DDD以来,我们团队经历了一系列的磨难--先是把核心项目 ...

随机推荐

  1. 【Unity渲染】一文看懂!Unity通用渲染管线URP介绍

    一.Unity通用渲染管线(URP) Unity 的渲染管线包含内置渲染管线.SRP.URP和HDRP.自从Unity2019.3开始,Unity将轻量级渲染管线修改为了通用渲染管线,这是一种快速.可 ...

  2. CAD和实时渲染之间的差距

    建筑师如何将他们喜爱的CAD工具与虚幻引擎和Twinmotion 等快速实时渲染工具结合使用 每个建筑师都有自己喜欢的设计工具.从Revit的粉丝到阿奇卡德的狂热用户,AEC专业人员通常首选CAD和B ...

  3. Mysql访问问题,远程连接提示:Host 'xxx' is not allowed to connect to this MySQL server。是mysql未开启mysql远程访问权限导致

    1.MySql服务器共享问题 对于在车间工作者,如果远程Mysql,我们这里假定网线连接 GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.3' IDE ...

  4. 【教程】深入探究 JS代码混淆与加密技术

    引言 在网络世界中,保护代码安全是至关重要的一环.JS代码混淆与加密技术则成为了开发者们常用的手段之一.本文将深入探讨混淆和加密的概念,以及其实现原理和应用方法,帮助读者更好地了解并运用这些技术. 概 ...

  5. 替代 Redis 的开源项目「GitHub 热点速览」

    近日,知名开源项目 Redis 宣布修改开源协议,从原来的「BSD 3-Clause 开源协议」改成「RSALv2 和 SSPLv1 双重许可证」.新的许可证主要是限制托管 Redis 产品的云服务商 ...

  6. LOTO任意波形发生器SIG82模拟输出继电器吸合断开的信号波形用于算法调试

    LOTO任意波形发生器SIG82模拟输出继电器吸合断开的信号波形用于算法调试 继电器吸合的电流变化过程是如图这样的波形,0到2的时间大约为17毫秒,2到3的时间大约38毫秒. 批量继电器产品吸合是否满 ...

  7. rust结构体包含另一个结构体引用时,serde序列化问题

    代码如下 use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Person { id: Stri ...

  8. 【Java面试题】Mybatis

    五.MyBatis 40)谈谈 MyBatis Mybatis 是一个半自动化的 ORM 框架,它对 jdbc 的操作数据库的过程进行封装,使得开发者只需要专注于 SQL 语句本身,而不用去关心注册驱 ...

  9. ASCII编码的全面介绍

    1. ASCII编码的定义和历史 ASCII(American Standard Code for Information Interchange)是一种用于将文本字符转换为数字编码的标准,最初由美国 ...

  10. Python企业面试题1 —— 基础篇

    1. b.B.KB.MB.GB的关系? b ---- 位(bit) B ---- 字节(一个字节等于8位) 1 B = 8 bit 1 KB = 1024 B 1 MB = 1024 KB 1 GB ...