zoukankan      html  css  js  c++  java
  • 模块化编程与不可信验证思维

     一、背景

    在软件研发中,总会出现这样的形象,同事小甲研发一个子功能模块,同事小乙研发了另外一个子功能模块。一个业务完整流程需要调用两位同事研发的两个子功能模块。业务数据出现了异常,同事甲和同事乙根据业务数据分别排查问题。最终结论为同事甲研发的模块出了异常,同事乙的功能模块在错误的数据上“正常”的运行完成(入参出现错误,错误数据的基础上,正常运行且完成)。
    思考:
    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. 核销模块使用流水信息时,获取对账单与关联的流水信息直接使用,不验证。
  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/wlandwl/p/check.html
Copyright © 2011-2022 走看看