标准化思想及组装式架构在后端BFF中的实践
总第505 篇
2022年 第022篇
-
1. 前言
-
2. 背景与问题
-
2.1 业务背景
-
2.2 研发挑战
-
3. 问题分析与解决思路
-
3.1 问题思考
-
3.2 标准化及组装式思想
-
3.3 我们的解决思路
-
4. 标准化思想及组装式架构在后端BFF中的实践
-
4.1 产品功能归类之系列化
-
4.2 功能组件提取与预组装
-
4.3 变化应对之可变性建模
-
4.4 可视化组装与配置填充
-
5. 总结
1. 前言
2. 背景与问题
2.1 业务背景
-
功能多 :在多业态背景下,信息展示功能总体上表现为功能模块非常多。主要是因为同样的内容会在多个地方展示,比如某个行业的商品信息会在App的首页、搜索结果页、频道页、详情页、订单页、运营页等多个页面进行展示。并且当新行业新内容出现的时候,又会全面铺开,进而导致增加更多的功能。截至目前,我们已有上千个展示功能,呈规模化势态。 -
差异大 :差异化主要体现在相同的内容,在不同行业、不同客户端、不同模块、不同版本甚至是不同用户条件下,都会有不同展示逻辑。比如商户详情页货架的商品标题这个字段,有的行业展示的规则是“服务类型+商品名字”,如“[玻璃贴膜]龙膜全车车窗隔热膜套餐”。有的行业的展示规则是“服务特性+商品名字”,如“[洗吹]单人明星洗吹+造型”。再比如跳转链接这个字段,H5、小程序和App内的跳转链接的拼接规则都不一样。诸如此类的差异几乎贯穿所有的功能。 -
功能易变 :主要体现在产品逻辑会经常发生迭代。分析变化原因来自多个方面,首先是这类信息产品面向海量互联网用户,用户体验敏感度高,细微的展示规则差别都可能会导致不同的转化效果,到底是哪个展示规则效果比较好,产品只能通过不断的调整来进行验证。其次,本地生活服务标准化程度低,内容本身的结构也在不断迭代,内容变更同时也决定了展示功能要跟着变。最后一点,互联网行业中产品的职责也会经常进行调整,不同的产品对功能的理解是不一样的,这也是导致功能更迭的原因之一。
2.2 研发挑战
-
场景一,由B端( 商家/运营 )直接生产出来的信息,不能直接展示给用户。B端主要关注信息能否高效录入,录入的信息不适合直接展示给用户,需要经过一些逻辑加工,同一份B端录入的信息可能会有多种加工展示规则。 -
场景二,由于B/C端业务领域问题差别较大,为降低开发难度,B/C端一般会做精细化分工,一拨人专注B端的信息录入能力建设,一拨人专注C端的信息展示。
-
问题1 - 效率 :天下武功,唯快不破。产品功能追求快速上线似乎是个永恒的命题,在互联网行业C端海量用户的背景下,这个命题尤为突出。此外,很小一个功能点的改动就会对用户体验产生非常大的影响。在人力有限的情况下,如何满足大量产品需求快速上线是研发团队面临的首要挑战。 -
问题2 - 复杂性 :稍微有点追求的工程师都会考虑代码复用的问题,不管代码写得优不优雅,绝对不能允许重复,于是代码中就充斥着各种 if…else…,因为有的逻辑只有当某些特定情况下才会运行。但是,复用需要良好的建模,嵌入过多的逻辑,只会让系统的复杂性变得越来越高,进而让系统难以进行下一步的演进,这通常会消耗大量的隐性成本。如何控制好系统的复杂性,让系统长期保持可理解、可修改,是我们面临的又一挑战。 -
问题3 - 运维成本 :如果缺少抽象的过程式开发,还会导致系统功能变得非常繁多,接口就好几百个,平时这些接口的运维工作也要耗费大量的人力。如果功能的开发缺少统一的章法,代码逻辑复杂交错,就会给运维工作带来非常大的挑战。 -
问题4 - 成就感 :根据马斯洛需求层次的理论,顶层是“自我实现”的需求。如果落实到工程师的日常,大家也需要在工作中找到成就感。可问题在于,如果每天都“过程式”地编写数据的查询、加工和组装的业务,对大家来说,很难产生什么成就感。
3. 问题分析与解决思路
3.1 问题思考
3.2 标准化及组装式思想
3.3 我们的解决思路
-
产品功能归类之系列化 :福特T型车生产的案例告诉我们,单一的产品无法满足市场化的需求,多样性更具备市场竞争力。但是高效的多样性需要范围的约束,所以现代汽车生产商会对产品进行系列化,比如宝马轿车有7系、5系、3系,系列化是厂商在效率和多样性之间追求平衡的产物。在软件开发领域亦然,组件的复用应该是有范围的,我们首先将产品功能进行系列化归类,进一步降低了系统整体的复杂性及设计难度。 -
功能组件提取与预组装 :组件标准化是组装式开发的前提,所以我们需要先将组件提取出来。在最终组装功能的时候,为了降低组装的复杂性,我们引入了“预组装”的概念。针对每个系列的产品功能,我们将通用部分提前组装好,将定制部分提前预留出来,定制部分包括功能和特性的定制,这部分可延迟到需要的时候再组装。 -
变化应对之可变性建模 :在电动车出现以前,所有的汽车几乎都需要燃油来发动,因此燃油机属于共性功能的需求。但是我们发现,有的车主是新手,对车子非常爱惜,因此需要全景的倒车仪。有的车主是老司机,他们根本不需要全景的倒车仪,所以全景倒车仪就属于变化功能的需求。不仅如此,我们还发现对于同样有全景倒车仪诉求的车主,他们也会选择具有不同特性的设备功能,这部分属于更细粒度的定制需求。所以,变化本身是复杂的,是有层次的,变化需要被单独建模,才能够被有效管理。 -
可视化组装与配置填充 :细颗粒度的组件带来了一定的组装复杂性,为简化组装过程,我们将可用组件呈现在用户的界面上,开发同学通过点击鼠标即可完成组件的组装,而对于功能特性组件的配置填充,也是在用户界面上直接完成的。
4. 标准化思想及组装式架构在后端BFF中的实践
4.1 产品功能归类之系列化
1)产品系列化
-
基于内容 :一个模块展示的内容通常分为主要内容和附属内容,不同展示模块最大的差别来源于展示主要内容的差别。比如以展示门店为主的模块和以展示商品为主的模块,不管是系统实现,还是功能形态,都存在比较明显的差别。因此我们首先把展示内容的主体是谁作为归类依据,将不同内容的展示功能区分开来。 -
基于样式 :功能展示的样式差别往往会决定展示数据的差别,如果展示数据差别较大,那么接口则不容易做标准化。比如商品详情页和商品货架模块,商品详情只展示一个商品,同时会展示更多的商品信息。商品货架模块会展示多个商品,但是每个商品只展示少部分的信息,商品货架模块还会展示筛选项。显然它们的接口很难统一,因此展示形式是一个重要的归类维度。 -
基于实现 :最后要从实现层面看好不好抽象,另外两个维度的抽象已经为这个维度打好了良好的基础。怎么抽象呢?比如有两个功能的步骤和依赖功能的组合能够抽象的大致相似,那么这两个功能可以归为一个系列。
2)接口标准化
4.2 功能组件提取与预组装
1)功能组件提取
-
根据查询条件查询商品ID,比如查询门店下可售卖的团单ID; -
聚合商品维度信息,这些信息包括商品的标题、价格、服务流程、优惠促销、标签等等; -
查询货架的筛选数据及商品的摆放规则,比如推荐、热销、新品等标签数,以及哪些商品放在哪些标签下面的摆放规则; -
组装结果展示模型,涉及聚合数据的再加工,如标题、标签的拼接。
2)功能组件预组装
4.3 变化应对之可变性建模
if…else…
,而且实际中很多项目针对这种问题的处理方式都是
if…else…
。
1)可变性建模
2)可选项爆炸问题
4.4 可视化组装与配置填充
-
编写将外部数据粘合在一起的代码,包括远程RPC的访问代码和数据的组装代码; -
依照PRD编写一遍展示加工逻辑; -
将加工好的数据字段填充在和前端同学一起定义好的展示模型上; -
构建和集成代码。
-
功能选择 :基于对产品需求功能点的捕捉,在预先组装好的组件活动图上选择当前要开发的展示功能所需要的功能组件,这一步操作决定了大体的功能点,比如这个货架需要筛选功能,那么就把筛选组件选中,不需要就不选。 -
特性选择 :功能确定之后再确定更细粒度的功能特性,比如选择展示模型组装组件之后,这个组件要组装多个字段,每个字段都有多种展示策略,再比如标题这个字段,到底是要带括号的还是不带括号的,此时需要勾选。 -
配置填充 :经过以上两个步骤,基本确定了当前要组装的展示功能所需的组件集合,但有的组件是有配置项的,比如前文举的查询商品ID这个组件,填充查询渠道配置项就是在这一步完成的。
5. 总结
6. 参考文献
7. 本文作者
阅读更多