ddd-change-in-trade

互联网行业追求“快速迭代”,在整个过程中,用户的需求总是善变的,那系统领域中又有哪些是不变与易变的呢。
针对到店综合多种行业各种不同的交易流程进行分析,我们基本可以归纳出:
领域源于需求,但高于需求。相对于善变的用户需求而言,领域知识和领域模型本身是相对“静止”的,是“不变”的,会随着需求逐步演进。

问题与挑战

(1)到综行业多,同一种类型的业务差异也很大
到综涉及结婚、丽人、亲子、休娱等10+大小BU,几十种行业,不同的行业有不同的玩法。即使是同一种预订业务,对于每种行业预订的商品、预订流程、结算流程,都有差异。比如ktv行业重时间包房管理,酒吧预订关注与订座位,体验课关注课程的时间预订。

(2)业务交易形态多样化
不同的业务交易形态开始产生,比如丽人医美行业客单量大,项目重决策,团购就不太适合,衍生出线上预付定金,到店付尾款的模式。另外丽人美甲、足疗按摩等行业用户层面更愿意带客,所以从团购衍生出拼团的业务形态。另外还有买单的场景, 不同的业务形态,发货的时间点、方式,核销的时间点、结算的逻辑都有差异。

(3)需要支持的平台能力丰富
交易流程整个环节中,需要对接各样的通用平台能力,例如点评-美团订单中心,客服系统、UGC评价。这么多业务,业务总会有一些定制化需求,如何能够统一快速支持,是一个挑战。

核心思路与解法

需求是千变万化的,不同的业务,不同的流程,如何能够稳定快速地支撑业务的需求是关键,主要考虑从以下两方面来进行。首先梳理出业务中的不变量,定下整体的领域模型与框架,再考虑通过配置化、开放定制化等能力去支撑业务定制化的需求。

梳理业务中的不变量

针对第一个问题,项目初期,我们计划搭建一套通用的预订交易流程系统,但是虽然是预订业务,每个BU都会有差异。所以我们针对已有的定制开发的KTV预订和足疗预订去做了分析和总结,判断整个预订行业中有哪些是可以抽象出通用能力的。首先我们基于现有的部分需求,整理出每个BU的预订流程图,最后发现对于预订而言,整个流程是相似的,较大的差异性主要在于预订的商品和接单的流程。基于此会发现订单、商品、购买接单、核销、结算这几个大模块都是通用的。整个需要提供较多定制能力的模块主要在于商品模型与接单的模型。确定好方向之后,我们再对于子领域进行更细粒度的分析,在接单模型中,我们将接单规则配置和业务逻辑拆分。接单的逻辑可能会变,但接单领域模型里接单的规则配置确是可以固定不变的。
在通用预订的交易流程系统基本完善之后,我们面临着第二个问题,越来越多的业务形态开始出现。以拼团为例,在预订交易流程的基础上,我们发现整体的交易流程的模型都一样可以支持,有较大差异点仅在于购买流程上。针对于拼团,需要整个拼团拼团成功,才会真正发券。后续的核销、结算流程都是一样的,针对这些不变的领域,仅需要对业务进行扩充,就可以支持。在支持多种交易形态的过程中,我们发现已有的对接的一些平台能力,例如客服、评价、诚信等,都会有些差异。都可以采取一样的思路,先抽象出不变的部分,再针对有变化的部分通过配置化等方式支持特殊的定制。

快速支撑不断变化的需求

(1)不同业务需要支持的不同场景

模型扩展:拼团等新业务刚出现的时候,原先模型可能无法支持的话,首先会从复用的角度去考虑对模型进行扩展。原先只支持到订单一个层级,抽象出父订单的模型-拼团,一个父订单下面会关联多个子订单。后续类似购物车等形态,都是可以通过此模型进行支持。

服务扩展:一些预订业务或新业务可能涉及到第三方对接的库存发货管理,我们通过新增服务的方式,将预订的流程开放出去,给到第三方接入的能力。这一块相对独立,支持定制,且不影响主流程。

(2)多样的平台能力的需求,如何稳定快速支持接入的需求

每一个新业务接入或者新的交易产生,对于用户中心订单列表、客服订单列表的展示和操作都有些定制需求,用户商户侧的评价也有展示的区别。主要思路:模块服务独立,不影响核心流程。单独子模块,再针对不同的业务提供定制化或者配置化的能力。

具体方案及拆解

整体技术架构解决方案的思路都是从领域与微服务化的思路去考虑,如何能够很好地去分析领域模型和服务拆分,我们主要会从下面几个方向着手。

(1)梳理业务流程中通用流程节点

在切分微服务之前,我们要做的第一件事情就是梳理业务流程。不妨找业务领域的专家咨询,通过与他们沟通从而了解真实的业务流程,并将其绘制成流程图。对于过于复杂的业务流程,我们也可单独绘制流程图,并增加相关的流程说明。当然也能提供相应的状态图,用于说明业务流程中所涉及状态的变化过程。花再多时间去分析业务流程都不过分,现在所花的每一分钟都是相当值得的。产品需求是多变的,但是对于交易流程而言,整体的领域模型基本是确定的。我们从目前互联网常见的一些业务着手分析:团购、拼团、预订、电商、外卖、猫眼等。

梳理完每块业务的整体流程后,我们整理下。

业务形态

发货模式

货物模型

核销方式

结算方式

团购

库存为主

团购券

到店验证

券核销后结算

拼团

拼团成功后扣库存

消费码

到店验证

消费码核销后结算

预订

库存/商家接单/第三方对接

消费码

到店验证

消费码核销后结算

电商/外卖

库存/商家接单

货物

用户收到货确认

订单核销后结算

猫眼

库存/商家接单

消费码/实体票

到店验证/收到货确认

订单核销后结算

通过整个交易流程的分析,大概抽象出来都是下面这个流程,每一个模块会有类似,也有差异。

(2)梳理出系统各种聚合功能模块

我们可以对系统的功能进行一个发散的整理,最终明确整个系统的核心“用户”。比如交易流程,核心“用户”就是订单,整套系统都是围绕着订单在走。

(3)归纳整理出业务的整体框架

基于上面的分析,我们可以整理出整块交易流程业务的整体框架。

(4)抽取公共服务(不变)

一般服务拆分首先考虑横向拆分。按照不同的业务领域进行拆分,例如订单、商品、消费码、结算等,形成独立的业务领域微服务集群。其次,要做好微服务的分层:梳理和抽取核心应用、公共应用,作为独立的服务下沉到核心和公共能力层,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。在业务流程中与业务不太相关的部分,我们可考虑将其剥离出来,并形成公共服务。例如,价格服务、库存管理服务、销量服务其他第三方接口等。一般情况下,抽取的公共服务都不太会经常变化,所以“一个月内是否会有频繁改动”这也是我们抽取公共服务的一个判断标准。我们一定要想办法将不变的东西从可变的世界中抽取出来。每种公共服务都对应一个微服务,每个微服务都有相关API,方便其他服务调用。目前公司推动的服务化就是在完善这方面的基础建设。

(5)定义业务服务(易变)

当公共服务抽取完毕后,业务流程中剩下来的部分就是业务服务了。建议刚开始实施项目的时候,不需要将业务服务的边界切得太细,可以考虑先“大切几块”,但需要确保每个服务之间尽量不要有依赖关系。换句话说,每个服务都是独立的,虽然此时服务的块头可能比较大。目前交易侧主要分了几块比较大的服务,后面针对丰富的需求可以再逐渐不断扩张。我们先确保这些大块头服务可以运行在微服务基础设施上,再不断将它们进行细化,拆解为更小的服务。

结果及收益

总结

多变的业务中,我们会发现核心流程基本不变,分支流程与业务逻辑是易变的。

针对于核心流程,如果有些需要品类与产品形态支持定制的,尽量通过配置化思路去解决。

而对于一些易变的流程或页面,可以分模块拆分出来,控制每个模块的影响范围,做到不涉及核心流程。

效果

目前交易流程已经支持了预订、点单、扫码付、一口价、拼团等多种业务形态,接入大小业务30+,日订单量10W,涉及到综所有BU。

通过对通用逻辑的抽象,目前交易流程新增业务1~2人周支持开发与联调即可。

能够在复用通用能力的同时,支持业务的定制能力。

未来的方向

目前领域模型的划分还是相对较粗,业务订单和统一订单的分工职责需要明确。

应用架构上,会针对不断变化的交易形态,拆分出更多业务逻辑层的服务出来。同时,后续也会提供越来越多的交易有关的平台能力提供给业务侧去使用。

针对业务复杂变化较大的发货服务领域,会做更细的拆分,把其中接单、第三方对接等等抽象出公用的基础服务,在上层支持丰富的业务定逻辑。