模块化编程与不可信验证思维

 一、背景

在软件研发中,总会出现这样的形象,同事小甲研发一个子功能模块,同事小乙研发了另外一个子功能模块。一个业务完整流程需要调用两位同事研发的两个子功能模块。业务数据出现了异常,同事甲和同事乙根据业务数据分别排查问题。最终结论为同事甲研发的模块出了异常,同事乙的功能模块在错误的数据上“正常”的运行完成(入参出现错误,错误数据的基础上,正常运行且完成)。
思考:
  1. 若一个完整流水线涉及到多个子模块,如四个以上,如何快速排查问题;
  2. 任意一个子模块出现异常不可避免,如何保证业务数据的正确性;
  3. 能不能及时发现错误,并终止错误的业务数据继续向下执行;
  4. 项目中成员编码水平不齐,怎样阻止错误向下蔓延;
基于多年编码的辛酸历史,本文主要阐述在模块化编程的前提下,基于不可信验证思维的一种编程模式。

二、模块化编程

模块化编程是一种软件设计技术,它强调将程序的功能分为独立的,可互换的模块,以使每个模块都包含执行所需功能的一个方面所必需的一切。模块接口表示该模块提供和需要的元素。接口中定义的元素可由其他模块检测。该实现包含与接口中声明的元素相对应的工作代码。

使用模块化编程,可以将关注点分离,从而使模块执行逻辑上离散的功能,并通过定义明确的界面进行交互。通常,模块形成有向无环图(DAG)。在这种情况下,模块之间的循环依赖关系被视为指示这些模块应该是单个模块。在模块确实形成DAG的情况下,它们可以按层次结构进行排列,其中最低级别的模块是独立的,不依赖于其他模块,而较高级别的模块则依赖于较低级别的模块。特定程序或库是其自身层次结构中的顶层模块,但又可以看作是较高级程序,库或系统的较低层模块。

三、不可信验证思维

  • 文学家说:宁可信其有,不可信其无。
  • 数据库专家说:这是一个悲观锁。
  • 测试人员说:来一个破坏性测试。
  • 吃亏上当的研发人员:拿到数据要时刻保持怀疑态度,先验证再使用。谨慎校验,谢绝背锅。
纵然是业务繁重,纵然是逻辑复杂,但是我们敢于怀疑,我们坚持验证每一个数据来源,一句话,获取数据先校验,使用数据先核对,不可信验证思维就是保证项目质量的关键!佛祖保佑,永不宕机!(套用例句:纵然是敌重我寡,纵然是身陷重围,但是我们敢于亮剑,我们敢于战斗到最后一个人.一句话,狭路相逢勇者胜,亮剑精神就是我们这支军队的军魂!剑锋所指,所向披靡!)
 
应用场景
一个流程多个节点的业务线,且不同节点之间存在明显的时间差,一般出现问题也是因为不同时间段数据发生变化导致的。
不可信验证思维关键点
  1. 合理拆分业务模块,保证子模块功能相对单一独立,不同子模块之间通过全局唯一的业务编码关联串行;
  2. 子模块的所需业务数据通过全局唯一业务编码获取;
  3. 子模块主动验证上一个业务模块产生的结果数据。验证合格继续处理,验证失败,终止流程并记录失败原因;

四、实例分析

  1. 案例背景

电商系统中存在分销业务,特别是网红时代,网红开店卖货也是一种分销模式。如某一个分销机构一个月有3000个订单流水,这些订单的实际收款流入到分销机构。这3000个订单在电商系统中未付款,处于未完结状态。分销机构定期向电商公司打款结算订单流水。

参数1:订单3000个。

参数2:分销机构A。

参数3:分销机构A提供N条打款流水记录

  1. 模块化拆分

电商系统要实现这一批订单的结算功能,可基于模块化编程开发,主流程参考如下:
对账单:指分销机构定期向电商公司打款结算的业务单号。
流水号:分销打款的银行流水信息。一个对账单对应多条流水信息。
本例中不同模块仅通过对账单编号流转(忌:上一个模块向下一个模块传递大量业务参数)。各个子模块之间可通过事件,消息等中间件模式解耦,不同模块应各自独立。
后一个子模块在处理业务时,根据对账单号自己获取所需数据,并验证所取数据的正确性。

流程参考说明图:
对账单核销时,考虑到订单数据量大,可基于后台任务处理,采用订单逐条核销的模式实现。核销流程参考如下:
一个订单适配一条流水:支付流水额度大于订单待核销的额度
一个订单适配多条流水:单条支付流水额度不足以核销一个订单的待支付金额
  1. 不可信验证思维
每一个模块在使用上一个模块产生的数据时,均先验证:
  1. 生成对账单模块:验证订单基础信息,订单是否被核销过,验证支付流水信息,判断支付流水信息是否还存在可用额度,是否正常。
  2. 核销对账单模块:基于对账单编码,查询对账单基础信息。如对账单要对账的金额,申请订单的总核销金额是否一样。对账单关联的流水信息是否可用。
  3. 核销内部实现模块:采用模拟核销,最终验证所有订单是否核销完成,模拟核销的金额额度扣款是否成功。
  4. 订单流水完成:分析对应订单的核销日志,核销金额是否与最初待核销金额一致。
  1. 大忌
  1. 在生成对账单模块完成后,传递对账单扩展信息给核销对账单模块,核销模块直接使用接收到的参数进行业务处理。
  2. 核销模块使用流水信息时,获取对账单与关联的流水信息直接使用,不验证。
posted @ 2021-02-05 15:47  无涯Ⅱ  阅读(865)  评论(1编辑  收藏  举报