在分布式系统中,数据一致性是一个很难题。通常都是保证可用性,实现最终一致性。最近在review代码过程中,发现代码一致性也很重要,很多小伙伴都容易忽略。
案例
一个发奖脚本,有两个功能:
1.打印获奖名单,发送邮件供产品经理审核。
2.给获奖名单的用户发送奖品。
开发同学在实际实现功能时,分别写了两个函数,逻辑大部分类似。只是打印函数加了发邮件和数据格式化功能,发送奖品函数调用发奖服务接口。
分析
这样做是有几个问题。
一、逻辑一致性维护的问题
同样的逻辑,分布在两个函数中,必须要保证两个地方函数逻辑一致。让以后维护代码增加了难度。一旦改漏,会导致审核和发送逻辑不同,很有可能导致事故。即使不出错,如果有修改,也要时时刻刻关注两个地方逻辑一致,增加了比对的工作量。
二、功能实现不完全
该功能只想到产品经理审核全部通过或全部不通过。万一产品发现中奖名单里有个用户不应该发奖,要怎么办?发奖函数完全不支持这种功能。为了实现审核功能,只能去改动数据库,无疑又增加了风险。数据库设计时有没有软删除字段,只能物理删除,在生产环境也是不允许的。
解法
两个函数有相同点,可以用两种方法解决。
第一种是把公用部分抽象成函数。两个函数分别调用。
但是在这个case里,还不是最好的办法。
由于审核和发奖是一个前后依赖的流程,把他们做成串行的,发奖的输入数据是审核的输出数据。
审核只负责导出名单给产品,让产品决策谁该发,谁不该发。发奖只负责发,你给我什么名单,我就给谁发,最多再加个校验逻辑,校验下名单中的人是否在最初的审核表格中存在。
把审核后的输出作为发奖的输入,就能把问题解决了。
总结
代码中维护逻辑一致性,可以用设计模式解决。
在实现产品逻辑时,也要考虑是否有逻辑重合,可以通过输入输出连接,串行处理,达到相同逻辑复用,也能降低复杂度,易于调试。