宋小菜技术的领域驱动设计(DDD)实践分享

冉鹏 发布于 2018/06/20

紫川:从 2015 年开始去组建技术团队,一直走到今天我们是第一场出来跟大家分享,之前也很少出来分享。过去3年时间,我已经实践了很多新技术和新的技术思想,今天想通过这样的技术会议和大家进行交流分享。

image.png | left | 747x416

我是紫川,跟刚才展堂一样也是从阿里出来,2015 年加入宋小菜,在宋小菜是作为架构师的角色。其实个人方向其实也是像刚才展堂讲的偏业务架构这一块,今天我会去从业务场景切入,介绍一下在宋小菜里面 DDD 和 GraphQL 怎么配合的。在讲之前跟大家互动一下,在场有多少做服务端开发的同学?(举一下手)好像还很少,今天的主场还是 GraphQL,是前端同学。 所以今天要改变一下讲课的姿势,我今天来打辅助,主要看一下领域驱动怎么配合 GraphQL 去落地的。

image.png | left | 747x411

开讲之前先抛一个命题, DDD确实可以保证和提升 GraphQL 的实施价值,这个命题在后面介绍里详细去分析和论证,大家如果有疑问可以马上提出来。

提问者: DDD什么意思?

紫川:我们用了一些思想和技术框架在整个业界不管是杭州还是整个中国地区还是偏冷门的,所以做这个东西的时候,也是有一种冒险在里面,所以我们希望走出去跟大家多去交流,看一下各行各业里面是不是有类似使用这种思想和框架的同学,有没有类似碰到一些坑,类似在团队里面实施不畅的问题过来交流,今天虽然是分享,但更多想去看大家怎么想这些新技术和新框架。

DDD 是建模的方法论,全称是领域驱动设计,缩写是 DDD。刚才在 GraphQL 群里面看到前端同学一直在说,以后如果用 GraphQL,前端同学不能安安静静丢锅了,确实趋势是这样的,以后整个的开发模式会颠倒过来,以前偏后端,以后可能会重前端,所以未来前端开发模式里面肯定驱动产品往前走,因为在 web 端的时候后端同学有可能把前端的代码全部都写掉,由后端同学来驱动前端去做,然后到今天这个重端技术发展潮流下面之后,前端同学更有主动权去驱动后端的同学去做一些事情。如果我今天介绍完之后,大家觉得 DDD 方法论比较好,可以向团队后端同学推广一下,可以跟团队里后端同学说“哥们你的接口定义太差,能不能用新的方法新的思维帮我定义好接口,这样我前端用起来更舒服,更贴近业务”。

所以今天的主题还是向前端同学介绍一下,是怎么样定义一些后端接口。今天不会讲的太深,有可能带一个科普性质,让大家有这个印象,有什么作用, DDD 为前端带来什么价值?

在讲技术框架和技术实施之前还是回到真实的业务场景里面去看,因为不管技术做的多牛逼多酷炫,总是为商业和业务服务,所以为商业和业务服务,还是要从业务出发,还是要回到业务本质看一下这个技术到底能带来多大的价值。

image.png | left | 747x416

首先开篇还是要简单提一下宋小菜的一个业务背景。宋小菜从 2014 年开始创始,从 2015 年开始有产品技术团队,然后去做平台,从第一天开始,宋小菜这样的商业模型和商业概念,就已经注定它是一个复杂多变的业务,因为它是生鲜 B2B,整个业务链路相当长,从第一天开始做就是反向供应链的思路,从销地到产地看,在业务链路上面有很多参与者,这些参与者在很多传统行业里面已经扎根几十年,决定了我们要服务的角色相当多。

image.png | left | 747x415

我们看一下宋小菜的整个业务链路,这个地方做了一层抽象,真实的宋小菜整个链路要更加复杂,环节也很多,这张图里面其实大概抽象了核心几个链路。因为从第一天开始整个业务方向叫做反向供应链,从销地,像类似杭州类似上海这样的销地市场出发,然后抓住销地我们服务的客户他的真实需求,我们现在服务的销地客户就是我们内部的行话叫小B,这是一个新的业务概念,菜市场里面大家可以看到那些卖菜的菜贩,就是宋小菜服务的客户,我们叫他小B。现在的业务链路先从小B开始,提供宋小菜 APP,让小B在 APP 里面下单,把整个区域的订单,这个区域有可能是整个华东区,或者华南区一些客户的订单集中起来,这个订单量有多大,现在基本上每天我们的日均吨位生鲜蔬菜这一块的吨位达到 800 多吨,这些订单聚合之后会流转到上游供应商那边,而我们服务的这些供应商现在基本上是全国最大产区的大型供应商,他们接到订单开始安排车次,安排司机,安排到他自己冷库里面装货,通过第三方物流服务,把这些货运到服务站,每一个菜市场有一个服务站专门针对小B服务的一个办公点,在这里面把货交给小B,所以宋小菜对外服务链路是这样的。

在内部其实我们也会服务我们内部客户,内部客户有三大角色,分别是销售、采购员和物流调度员.他们的职责分别是:销售为小B服务,主要工作就是拿订单,采购员针对供应商提供服务,向供应商发起采购,物流调度根据采购单里需要配送的货物发起车和货的调度,需要调度的货物配送的目的地分散在全国,现在宋小菜全国 40 多个城市开展线下业务,这些调度在里面还是相当复杂的,是要根据整个全国订单的情况去做分拣和拆单工作。上面讲的就是宋小菜当前一个大概的业务情况。

image.png | left | 747x405

接下来宋小菜的技术背景也要提一下,为什么我们会去用 DDD,为什么要去使用类似 GraphQL 这样的新框架,在之前在杭州地区还没有看到过其他的团队有使用过,也很少听到过一些其他的创业公司用这样比较新的技术框架。而 DDD 其实不算一个新的设计思想,以前是一直在传统行业在用,最近几年开始在互联网公司大面积去实施的。

所以讲到这里还是回到技术背景去看为什么要选型这样的技术,第一个原因是在前端端协同效率提升已经出现瓶颈,之前 Scott 老师已经跟大家简单介绍了一下整个宋小菜开发的流程,在里面可以看到在系统设计阶段到最后的接口 Mock 其实是前后端协同的瓶颈,所以这个瓶颈出现之后我们是想去突破它,因为整个 B2B 行业里面本质来讲效率是第一的。不管是技术还是业务都是以这个为出发点去做业务做技术的,所以我们是一直想不断提升我们整个开发效率的。

第二个大的背景是前后端对业务的认知已经发生分歧,这是业务决定的,因为刚才介绍业务背景里面,业务链路长,又复杂多变,整个的服务角色又多。这里面一些业务术语大家在其他行业没有办法想象的。待会儿后面讲的周文宇,也是 B2B 行业里面的纺织业,肯定也有这样的同感,在传统行业里面业务相当复杂的。链路这么深的情况下,所以难免会出现整个公司里面,其实不管业务方还是产品经理,还是开发,有可能对同一个业务术语理解是不一样的,这是为什么要用 DDD 去定义我们的业务。

image.png | left | 747x412

接下来大家看一下宋小菜之前的架构图(后面同学可以看到这张图么?),这是之前宋小菜老的架构,很典型互联网那套架构,在这个里面先简单介绍一下,让大家提问让大家发现一下这里面这套架构有没有问题。可以看到上面这一层,上面这一层就是我们端,刚才 Scott 老师介绍现在端对外有三款对内有三款产品,这里面的端叫交互层,中间一层叫网关层,网关层这里面为什么会分开?是有一个网关平台和网关框架应用,在第一代架构里面临时搭了一套网关架构去约束 API 定义的,后面发现还是要集中去管理这些 API,所以会有网关平台出来,这是我们在使用 DDD 和 GraphQL 框架之前的架构,这里面还有一层叫网关接口层,把内部所有的业务流里面的业务数据封装组装一些数据,提供这样的接口出来,通过网关这个框架去透出 restful 的 API,提供给端去使用。下面是各种服务,各种链路上的服务都在这里面,所以我想问一下大家看到这里面整个架构里面有问题吗?

提问者:直观感觉给我的感受,跟我们可能遇到类似,就是订单中心或者商品中心它独立拆开之后,LODGS 比较适合做微服务化,对那个稍微了解一些,它的拆解颗粒度太粗了,会导致一些系统的可维护性与可被测试性会非常弱,就很容易变成了黑洞级别那种东西,可能理解不是非常好。我自己的大概理解是这样。

紫川:其实这张图里面大概画了一些,其实我们服务拆的比较细,但是服务拆的细还是有问题的,后面如果有第二届或者第三届的 GraphQL 的分享会分享我们团队之前碰到的问题。其实微服务的概念从 2015 年火起来,很多团队尝试用,但是用的不好,还是有原因,如果后面有专题还是希望跟大家分享一下这些。我们微信的 B2B 技术分享公众号,里面写了一篇文章专门针对微服务实施这一块碰到一些坑,大家可以看一下。

这里面其实我们可以看到,这一层其实在整个的系统里面没有太多价值的,为什么这样说?因为系统其实是为业务去服务,在这一层里面其实没有太多业务的一些沉淀,纯页面的一些数据组装,这里面占据了部分的开发人力在里面,后面会去讲,所以这一套老的架构决定之前提到的开发模式。

image.png | left | 747x412

开发模式刚才 Scott 老师也提到,在这个里面很典型的互联网公司一些开发模式,从需求讨论开始到产品 PRD 评审,到 UI 评审,整个链路有 12 个节点,整个开发分两周,两周一个小迭代,去推进产品往前走,所以这里面有 12 个节点,基本上每个节点只有半天时间可以去使用,在前后端协同里面,系统设计到接口 Mock 会占到 3 到 4 天的样子,基本上占到大头,因为整个架构模式偏向页面驱动设计去做的,所以一定要等到UI评审之后系统设计才能启动,就是后端开发同学才能去设计接口,去设计系统,然后接口设计完之后才能进行接口 Mock, Mock完之后,这个时候前端才能介入进行代码开发。有可能之前前端同学会在系统设计阶段和后端同学一起按照 UI 的页面去画页面,但是如果它提前去做 UI 页面画页面的事情,会在后面流程出现一个问题,就是之前讲到技术背景里面前后端对业务的认知发生分歧,每个人因为他的一个工作的角色决定他对业务理解不一样,这个地方发生的分歧很典型对页面业务字段定义会不一致,不一致导致的结果在集成测试,把这些问题暴露在集成测试这个阶段,前后端连调的时候,往往因为业务字段不一致,导致一些后端数据没有传给前端,有一些数据前端传给后端,后端同学没有存储下来,会造成整个项目过程中一些不必要的 bug 存在。这时我们发现前后端协同上面已经出现问题了,所以要推进我们去找解决方案优化。

image.png | left | 747x402

刚才讲的例子可以看到页面驱动带来一些不好的地方,第一个就是我们的技术设计严重依赖 UI 设计,一个页面对应一个后端接口。一旦交互和视觉调整之后就会带来整个前后端开发同学整体调整,前后端开发流程又被这个 UI 页面绑住,不能独立并行开发。第二个后端同学在这里面做了大量苦逼但是没有技术价值的事情,这些事情基本上浪费整个项目组里面 25% 的开发工作量。刚才也讲到前后端对业务的理解不一致,在集成测试阶段会暴露出来,这个时候大家又会花大量时间去沟通,往往很小的项目本来一天集成测试有可能会完成,但是在业务比较复杂的情况下有可能需要花两三天的集成测试,最后会发生技术实施的妥协。这里面很典型一个案例,如果前端同学是一个老司机,会强奸后端同学改字段,一旦改字段按照前端同学去理解,这个字段就不是真正业务上的含义,所以为什么叫畸形的方案妥协。

右边 2 张图是真实线上 APP 展示的页面,在两个不同 APP 上展示 的,第一个是我们的宋小菜 APP,为小B(为菜市场菜贩)服务的一个 APP 里面一个商品列表页面,右边这个页面是为销售服务的宋小福 APP 的报价页面。这两个页面基本上长的一模一样,但是在老的开发模式上面,在后端其实开发两套接口去提供类似的数据,这是在整个后端代码 review 的时候经常会发现的一些问题,就是不同的项目组里面开发类似的接口,重复的开发,所以造成刚才讲到网关接口层那一块服务端已经累计产生了 111 个面向页面的类,这还不包括具体的方法,这些类里面代码其实很臃肿,但是又没有太多的业务价值,因为业务价值不是通过页面组装去表达出来的。

image.png | left | 747x410

通过三年的一个业务迭代和技术的一个持续开发.我们发现页面驱动这种设计方式没法满足业务的发展要求的。在做传统行业改造的过程中发现整个业务天然是易变的不确定的,业务易变和不确定带来一个问题就是公司很频繁进行业务打法的变更,一旦打法变更有可能带来对于产品功能需求的变化,进一步带来 UI 功能交付的变化,这时候如果按照页面驱动设计会让整个团队疲于做功能支持,而没有真正沉淀核心能力,就是系统的核心能力。所以我们就是要改变这种方式。

image.png | left | 747x416

Scott 老师过来宋小菜之后带来 GraphQL 这个框架,给我介绍之后我觉得这个框架有可能会去改变我们现在的开发模式,所以从 2017 年开始,我们就去尝试它,基于这个框架又去重新把整个系统架构重新梳理了一遍,在这里面是想基于 GraphQL 这个框架做两件事情:

第一把刚才老的架构里面中间有一个网关接口层可以去掉,这一块去掉之后可以节省我们 25% 的开发量,在新的架构里面大家可以看到,没有网关接口层。第二个想让 GraphQL 改变的是,彻底做到前后端分离,刚才整个开发模式里面,在系统设计和接口 Mock 三个节点里面整个前后端协同是堵塞的,所以我们希望前端可以独立参与产品功能的开发,以及往后面走可以想象前端可以根据 GraphQL 去封装带有业务场景和业务价值、具有业务含义的一些 GraphQL 组件出来。这样的一个好处是未来前端同学也不需要介入开发,由产品经理自己去拼前端 APP 的交互,这个是可能出现,这不是 YY。

新架构里面网关平台开始集成 GraphQL 的使用,在这个里面其实可以看到 GraphQL 承载很大的作用,包括服务路由调用, GraphQL根据 scheme 的一些定义可以路由到后端提供的不同的接口,然后访问服务端之后进行模型的组装,将数据模型返回给前端。基本上把刚才说的网关接口层功能给替换掉,不需要多花费 25% 的时间去写这个接口。这是带来第一个价值点。

image.png | left | 747x413

我们再看一下,如果说简单的只用 GraphQL 来代替网关接口层会不会可以解决刚次我们提到的所有问题。其实在内部也讨论过,也去推理过,我们就基于这一套思路去推理,后面有可能出现的情况是,如果服务端还是按照页面驱动的那种方式和思想去做服务端接口定义,发现有三个情况会出现:

第一个长期发展下去,过半年或者一年以后还是没有抽象的稳定的后端接口出现,后端接口还是随着页面的变化不断调整。

第二个还是会发生一个页面对应一个后端接口,不同的开发同学有可能会开发出重复的后端接口。

第三个情况是后端接口泛滥,这时候 GraphQL 就失去它进行数据模型组装的价值,因为找不到确定的数据模型,有可能两套接口里提供同样两个商品列表的数据,但是不确定到底调用哪个接口来封装数据模型,最终导致 GraphQL 没有办法实施。

image.png | left | 747x411

回到这里面发现 GraphQL 实施需要确定的数据模型的。刚才讲到业务是不确定,易变的,而通过 GraphQL 去持续沉淀业务组件需要确定数据模型。在宋小菜业务背景下,只拿 GraphQL 框架来实施,会碰到 GraphQL 无法实施落地的问题。

image.png | left | 747x410

DDD 是可以提供确定的数据模型的,我们是在 2016 年开始接触 DDD 的,刚接触 DDD 的时候,发现领域驱动设计这套思想其实天然可以解决面对业务多变业务不确定时候,怎么样抽象和定义线下业务中实际事物的问题,在我们的两年多实践里面,对 DDD 基本上有这样的感知的,不管前端还是后端同学。

image.png | left | 747x411

所以讲到领域驱动设计,先介绍一下领域驱动设计是什么?后面乔禹同学有一个专题专门讲领域驱动,他会讲的比较详细一点,这里面由于时间限制简单的普及一下这个概念。

image.png | left | 747x413

其实领域驱动设计就是一套建模的方法论,回到建模上面来,建模到底是什么概念?简单说对于现实事物的抽象和定义,这种抽象和定义其实带有强烈的业务场景和业务需要。有时候定义一个客户这个概念,放到不同场景下面,大家对他理解是不一样的,所以你去建模带有场景特征,领域驱动设计这套建模带有场景的概念在里面的,在两年的实践里面发现领域驱动设计可以帮我们解决的问题(这是从后端同学一个角度去看),第一个是合理进行服务划分和治理,这个其实要贴合微服务实施去讲,微服务里面大家都在讲把服务力度拆的越细越好,这里面会带来另外一个问题,拆的越细越好怎么去拆?

提问者:设计原则指出,不管系统怎么样的,只要能被测试,开发人员就可以将系统拆分出来。打个最简单的例子不管给你一个数据方式你能证明它,所以微服务设计的时候那套系统不管怎么样去设计,我的原则它能被测试,单元化测试就 OK,就可以按照这种颗粒度去拆分系统,够用就好。

紫川:其实这里面(微服务),如果你从概念上去理解没有问题,一旦实施或者落地之后你会发现一个问题,问题是什么呢?就是你为什么应该拆成独立服务出去,碰到哪些业务问题要去拆它,业务价值在哪里?其实我们发现在整个系统架构上面一定要贴合你的团队组织或者公司组织形态去进行服务拆分和设计,如果你的服务拆的越细,就会增加整个开发沟通协同成本,所以不是一定拆的越细越好,还是根据整个团队规模去考虑的。所以使用领域驱动设计就可以很好的知道怎么样拆分服务,去治理服务,避免系统上面的业务耦合。第二个领域模型可以准确表达业务语言,不管技术同学,还是业务同学和产品同学可以通过领域模型对业务需求达到真正理解。业务方经常会给我们提需求的时候,带来各种各样的业务术语进来,这种业务术语其实要去抽象成模型,然后在业务场景下贯穿进去。如果不在领域模型的基础去沟通交谈,我们就不知道服务什么样的客户和然后客户到底碰到什么问题,领域模型帮助我们抽象这些业务。领域模型其实不止帮忙开发同学理解需求,也帮助到产品同学,我们后面想在整个开发流程里面,在系统设计阶里面,让业务方和产品经理能进来一起探讨,将业务元素进行高度抽象和定义,让大家都能在统一语境下理解业务。将领域模型在业务场景下串一遍,会让业务方、产品经理、开发同学觉得这个领域模型按照业务思路可以跑下来,这样让业务方和产品经理得到在系统实现业务目标商的确定性,另一方面开发同学能得到对业务理解正确的反馈。

image.png | left | 747x402

再讲到 DDD 和 GraphQL 结合实施的价值,以前端同学视角去看,有三点:第一, GraphQL可以将领域模型的业务能力体现出来, GraphQL可以实时聚合数据模型,可以快速支持 APP 的页面展示,充分发挥领域模型的价值。领域模型是高度抽象,可以通过 GraphQL 在各种产品功能用例和业务场景下快速聚合透出模型,让这些模型在业务场景下得到价值的充分体现。第二, DDD提供了具体业务场景下确定性的模型和接口,减少 GraphQL 和 schema 的重复定义和服务接口的重新调用。服务端一些接口如果不稳定或者不确定去做 GraphQL 和 schema 定义的时候会多变,会给前端带来重复开发的成本。第三,基于领域模型可以统一前后端同学对于业务的认知,基于统一的业务模型交通和交流,简单明了获取到对方的一些反馈。DDD 和 GraphQL 结合在我们团队已经在实施,特别是在 2018 年开始用 DDD 启动内部的方舟项目,全面重构和设计服务和服务端的系统。

image.png | left | 747x413

今天的主题还是怎么实施的,刚才一直讲很虚的东西,很概念性的东西,怎么落地才是大家关心的,最后下面简要介绍一下在宋小菜里面怎么样去落地领域驱动设计的,落地之后领域模型怎么样支持 GraphQL,然后给前端同学提供确定性的接口。

image.png | left | 747x401

这是整个实施流程,实施流程分四个阶段,第一个阶段是业务需求阶段。在业务需求阶段,开发同学不理解技术开发为什么要介入业务需求阶段,因为 DDD 本身是让开发的同学往前多站一步,让他提前介入到业务的探讨和业务的理解,在这个里面开发同学要做的事情第一个要明确业务需求想解决的问题是什么,问题的边界多大?问题是怎么定义的?然后在业务问题里面具体的业务场景是什么?这个过程中反复跟业务方交流跟产品经理交流的,可以获取和沉淀出业务术语出来,而业务术语是关键的业务元素。第二个阶段是产品方案阶段,这个阶段产品经理会产出 PRD,沉淀产品模型的一个阶段,这个里面开发的同学也可以介入进来,这个阶段里面说的一些东西在(宋小菜的微信公众账号) B2B 技术分享里面也会去提到.这个里面开发同学要去确定产品用例,产品用例里面的一些业务术语抽象成领域模型。到了技术方案阶段,刚才讲的用领域模型去套产品用例,套这一业务场景,看一下领域模型到底设计合不合理。最后通过两年时间的实践会有一套 DDD 实施规范出来,后面会讲一下为什么 DDD 实施一定要有完备的一些规范,因为没有完备的规范去落地,有可能会出现各种状况。这个就是 DDD 实施的大概流程,今天大概讲了一下,后面乔禹同学也会详细分享领域与设计实施那块,这里只是简单介绍一下在宋小菜的 DDD 实施的规范。 这里分两块,第一个是工程模块的管理规范,后面是在工程里面包的一个结构规范。后面有同学对这个感兴趣可以交流一下。

image.png | left | 747x414

刚才有同学讲到微服务的概念,(我们这里也是按照微服务的概念去定义子工程),整个宋小菜用户中心工程结构中这几个模块部署在一个系统里面,它其实在一个进程里面的,如果将来发现(用户中心工程)里面有一个子模块,整个访问量越来越高或者支持的业务场景越来越多,业务规模越来越大的时候,可以快速从这个工程里面抽出来,单独拎一个启动包,然后单独部署的,这个是我们基于 DDD 设计出来的可以快速支持业务变化的一个工程结构。

image.png | left | 747x392

这里面简单介绍一下在每一个工程里面的包结构,这个包结构分了三层,第一层叫应用层,第二层是领域层,第三层是基础设施层.应用层做的两个事情:第一个暴露服务能 力。第二个是隔离领域层,防止业务泄露。在过去三年时间里面发现很多系统里面会搀杂相同业务元素,比如说宋小菜交易的业务场景里面规定 7 点之后不能下单,因为要根据当天的订单快速去采购去调度货物,业务上限制 7 点之后不能下单,这个业务规则在很多其他非交易系统里面都存在,不管是服务小B还是服务供应商的系统都会用到,这个业务真正应该沉淀的地方是交易中心,应该由交易中心来管理。但是因为当时没有去约束,所以造成这个业务规则散落在各种系统里面,一旦后面去调整,把7点之后不能下单这个规则打开,调整到 12 点或者 11 点,这个时候要改多个系统。所以应用层的作用去保护系统里面业务规则不会泄漏到其他系统,把它沉淀到领域层里面。第二层领域层负责沉淀和保护业务模型,以及保护业务规则,在领域层这里面其实都是很纯粹的业务表达和业务术语沉淀,不带任何技术框架和技术实现的。真正的技术框架和技术实现都沉淀在基础设施层里面,这个为什么要这么分?是因为领域层的东西是稳定的,外部的技术选型变化不应该影响领域模型。例如一旦基础设施里面存储方式变化了,我们现在用的是 MySQL,如果以后换成其他 DB 或者其他存储的话,是不应该影响领域模型的结构,如果换成 MongoDB 只需要切换到新的存储结构就OK,不需要动整个工程的代码。

image.png | left | 747x416

最后讲一下 DDD 实施的一些建议,这也是我们在过去三年里面遇到的一些坑总结下来的经验教训。第一个建议,因为 DDD 是一个高度抽象的方法论,所以不建议大家教条化去实施,特别是使用 SSM 三套件的团队,因为 DDD 本身和 Spring 那套思想有冲突的地方,实施的时候需要根据业务情况和技术团队的情况做权衡和取舍第二条建议,因为 DDD 高度抽象,上手门槛和实施门槛相当高,从一开始拿来尝试的时候我们已经看清一点不可能让团队里面所有同学都去理解,所以刚开始去实施的时候让团队里面开发经验比较丰富,特别是做业务系统经验比较丰富的同学去尝试和实施的,这是为什么?因为开发同学必须要有一些抽象能力在里面,有一些系统性的思维和抽象能力在里面,才能去理解 DDD 的整个实施过程的。第三条建议,因为它是一套方法论,在实施之前我们是一定要有一个完备的规范,刚才我后面两页 PPT 里面讲到一个工程规范一个包结构规范,为什么一定要有这个规范呢?因为做设计的架构师同学,他的思想在业务场景下总是很抽象,他想表达有可能是他真正看到和理解的东西,但是实际写代码和开发的同学不理解架构师要的一个模型,这个时候实施里面碰到这样的问题,开发同学不理解领域模型的设计,会经常去问实体和值对象到底放在哪个地方?觉得放在哪个地方都不合适。所以肯定需要有一套规范保证开发的确定性,所以有了刚才整个包结构的严格执行规范,就是你定义你的实体你放到这个包里面,定义的值对象放在这个包里面。
最后谢谢大家,到最后提问环节。