其他分享
首页 > 其他分享> > 基于 DDD 思想的酒店报价重构实践

基于 DDD 思想的酒店报价重构实践

作者:互联网

1. 前言

Domain-Driven Design,简称 DDD,翻译过来就是领域驱动设计。这个概念是从技术的视角提出的一种系统架构设计方法。网上能查到的大部分资料基本都是技术视角来阐述,列举的案例也都是代码形式的案例,非技术人员很难看懂,而技术人员去看,不同的技术人员理解上差异很大,之后在落地系统设计的时候往往无从下手,有时又感受不到 DDD 具体带来的优势,甚至一些尝试失败后,可能对 DDD 持负向态度。

DDD 是一种处理高度复杂领域的设计思想,它试图分离技术实现的复杂性,并围绕业务概念构建领域模型来控制业务的复杂性,以解决软件难以理解,难以演进的问题。因此 DDD 应该是以业务重塑为主,以系统重构为辅,在团队内对业务的运营方式、系统分工及边界建立共识和原则,同时兼顾业务未来发展的扩展性的系统工程。

本文将结合实际的基于 DDD 思想的酒店报价重构项目,从 DDD 推荐的战略设计(借助头脑风暴等确定模型,相当于确认需求)、战术设计(确定架构模式及代码规范,相当于确认技术方案)、系统实现三个核心阶段讲解 DDD 在整个过程中的巨大作用,同时涉及各个阶段目标及产出,希望这些实践能对读者有一定的指导作用。

2. 重构背景

先来看一下重构前梳理的报价计算的主要过程:

图片

从上图中可以看出报价系统的业务比较复杂,可以看到一个现象:只要跟“价格”相关的业务都耦合在这里,但不同业务关于“价格”又有各自不同的含义。按照业务视角拆解一下:

图片

从这两个图可以看到,报价系统做了很多不是“价格”的业务,对接了很多不同的业务团队。站在各自团队的角度来看,自己的业务需求涉及到了“价格”自然而然就去找了报价团队,每个团队也只关心自己的 KPI 是否达成,需求是否实现。技术团队似乎又不能拒绝业务提过来的需求,每个需求看起来都很合理(至少表面上是)。结果就是系统变成了一个大杂烩,出现如下的问题:

出现以上问题的原因:

为了能有效的解决上面的问题,我们开始了基于 DDD 思想的重构,核心是:产品和技术坐在一起,讨论业务玩法并达成共识,借助“域”的概念,搭建新的模型完成对业务进行重塑,既能满足已有核心业务,又能为未来业务发展做好规划。过程中,划清业务界限和定位,之后共同作为领域专家守住领域,对不合理的需求说不! 

3. DDD 之战略设计阶段

3.1 头脑风暴:领域专家为主,技术为辅的梳理与讨论

在这一阶段,最核心的角色就是领域专家,重构之前主要是产品经理(PM)这个角色。这个阶段要做好,像普通的需求那样,大家一起简单的讨论一下,方案可行就去实施,这样是不 OK 的,容易陷入为了 DDD 而 DDD 中,效果不一定好。基于 DDD 思想进行重构,需要注意以下【两个前提】

这里需要注意【一个原则】

同时需要注意【一个方法】

在这一阶段里,产品可以输出实际的业务玩法,包括核心的业务玩法、临时的业务玩法等,让产品和技术快速在业务的理解上达成共识,为后面讨论实际的模型做好铺垫,大家能知道新模型的重点该解决什么问题、要在那方面做好扩展。以报价为例举例说明产品输出的业务玩法:

同时,这一阶段,还要对业务瘦身,确认无用的业务、无价值的业务、一些模糊的业务场景,一起拿出来看看是否还需要,不需要的优先去掉,避免对后续讨论模型造成影响。由于系统迭代的时间太久,这一部分需要技术认真梳理代码,辅助补充好相关的业务场景和玩法,产品做好决策,要不要以及未来规划。

3.2 构建模型:解决已有痛点,治理杂乱流程

重构的核心是要把之前杂乱的流程治理好。在这个过程中,还要收集产品侧和技术侧的痛点,统一模型时除了保证对业务玩法的覆盖和规划,还要能解决已有的技术及产品痛点。这个过程主要分两步:抽象化、标准化。

图片

图片

通过上图也可以看出,新的报价“域”已经划出来了,每个“域”包含的属性及要做的事情也清晰了,从一个原始的代理商价格,到经过处理最终展示给用户的价格,整个过程也清晰了。

这些完成,产品侧和技术侧已经基本明确本次重构可以达成的目标:业务重塑(含瘦身)、技术架构重建、解决已有痛点、业务达成共识。其实在这个时候,产品和开发基本已经对业务大部分达成共识了,沟通起来明显容易很多,后续阶段则是对这种共识的不断加强和深化。

4. DDD 之战术设计阶段

共识的模型出来,开始进入战术设计阶段。这一阶段,核心是基于战略设计阶段讨论出来的模型,确定实际使用的架构模式及代码结构规范。

我们采用的是比较流行的:分层架构+整洁架构,按照 DDD 推荐的结构分为 User Interface、Application Core、Infrastructure 三层,如下图所示:

图片

在这个分层架构里,每一层我们又做了职责的确认:

这个模型里报价核心的“域”都在 Application Core 里,我们按照之前的域模型设计,结合实际的计算流程和业务形态,做了进一步细化:

图片

定义好实际的架构模型后,开始确定代码结构规范。我们内部的核心要求是:约定大于规范,并兼顾开发习惯。具体为:

至于 可编排可视化,主要是在开发过程中处理,我们也放到研发阶段去具体谈。

5. DDD 之系统实现阶段

这个阶段,核心角色正常已经变为技术,但是产品依旧需要结合最终的模型的去和技术不断的对实际流程里的细节。这里单独提一个报价这边做的不错可以参考的地方,产品非常负责任的把报价计算过程中所有细节进行了文档化,该举例子的举例子,该画图的画图,既是开发过程中的核心参考,也是之后新人学习提供了极大的便利。产品这么认真,开发自然也不差,将代码设计、核心流程也都通过各种图表记录下来,非常的实用。产品和开发在这个阶段产生的文档及图表,潜在的价值特别大。

这种大规模的重构,自然容易在过程中遇到一些问题,这里对几个核心的问题及应对做下总结:

接下来说一下借助 可视化 解决日常排查问题的痛点。我们对排查工具也进行了完全重写,借助新模型将报价计算过程标准化,单独针对工具请求,将报价计算过程中涉及到的核心数据全部放到上下文 debug 信息总输出,之后按模块进行渲染。这样通过工具界面请求,就可以把报价计算每一个流程进行还原,快速获取本次报价计算核心数据,这样一个简单的工具实用性极强,后期上线后值班报价不展示类问题直接降了90%以上,因为大家都可以很容易通过工具去查明原因了。当然这个工具可维护性也极强,工具如下图所示(部分核心信息隐藏):

图片

这部分还剩一个 可编排 问题。报价计算过程中,受限于不同的渠道等因素,涉及到的计算流程是不完全相同的,因此存在能力复用及编排的可能。我们整理了不同渠道的流程后,发现主流程及其他流程差别较大,且不同渠道的流程一旦确定是不会修改的,如果去做动态编排反而可能会引发故障,同时如果新增一个渠道基本0.5pd 就可以完成,因此我们虽可以通过代码支持编排,但实际中并没有投入时间去设计和完成编排这个功能,避免出现有名无实。

图片

在开发及验证都完成后,我们按照指定酒店、指定小城市酒店、热门城市酒店、全量城市酒店这种灰度流量的方式逐渐放量进行验证,前后3天完成全量发布,整个过程平稳,没有出现明显问题。

6. 后评估与总结

这次重构跨度3个月,进入开发到全量上线花费了1.5个月,比预期提前一天全量,实际带来的内部效果这里就不表述了,单独从各方感受做下总结:

这里,也总结一下 DDD 在这个过程中的重要作用:

DDD 为核心系统重构带来了新的思路,希望有更多的团队能使用它并用好它^_^


标签:重构,核心,玩法,业务,报价,DDD
来源: https://blog.51cto.com/u_15127643/2769357