M*N个策略造成类爆炸怎样重构?

背景

收到朋友针对他们遇到的具体问题写一篇文章的邀请,问题是这样的

朋友:

我们公司对接了M个三方服务  然后还有N种业务  实现用策略的话感觉有点类爆炸  也想不到什么好方法了  这也是早上刚接到一个重构支付的需求想到的   根据业务和供应商搞了太多策略实现了[晕]

我:

初步感觉应该用打造接入平台的方式解决

朋友:

开始的时候没有考虑到  代码一言难尽了 [捂脸]  谢谢谢老师

我从对话中分解出下面几个问题

1、理解重构、重写和重新架构

2、怎样做重构?

3、重构过程与业务支撑之间怎样平衡?

下面我针对这三个问题展开论述。

理解重构、重写和重新架构

重构是对代码和功能进行渐进式改进;重写是要摧毁它,重新构建;重新架构在大框架上做修改和再设计,具体每个实现模块可能是用原来的。

举个例子,搭积木。重构就是我用积木搭建了一个小马,发现小马某些部分不好看,我就把几块积木调整调整,让小马更好看;重写就是我用积木搭建了一个小马,发现自己搭建好了完全不喜欢,把积木推到了重新搭,既然是重新搭,搭好的东西和原来差距有多大就不好说了;重新架构就是我用积木搭建了一个小马,发现自己其实想要个小桥,没有必要全部推到重做,而是可以先画好设计图,然后直接把小马的四条腿拆下来做桥墩,脊背部分做一部分桥面,实在不能用的再拆下来重安装。

重构是小步跑的过程,如果对外提供的功能没有变化,这是稳妥的方法;重写往往伴随着功能上的升级,不然对于“我不知道这段代码是干什么用的但我不敢删”这种事情很难保证对外提供的功能没有变化。

重构和重写与修改量没有直接关系。有个哲学问题叫做“特修斯之船”,是说一艘船持续的在海上航行,船不断有部分老化或者坏掉进行替换,最终整艘船的所有部分都换过一遍,这时候船还是原来那艘船吗?

866e5c359b35084386cc7c9169e0adc9.png

所以咱们不再纠结概念,统一用重构这个词,聚焦于怎么解决问题。

怎样做重构

首先需要对系统进行一个生命周期预估,包括:

  • 未来需求预判

  • 模块划分拆解

  • 总结历史问题

朋友说:“开始的时候没有考虑到  代码一言难尽了”,其实大可不必这样想。架构和代码不是设计出来的,是演进出来的。如果一开始要我做,一段时间之后,也很可能会遇到相同觉得非重构不可的情况。虽然我一定会做未来需求预判,但是现实往往会出现很多例外情况,让程序充满了妥协。

那针对朋友遇到的问题,怎么设计更合理呢?

支付重构

如果只是重构支付部分,我个人觉得相对容易。因为支付需要的要素比较好抽象,主要是下游支付渠道需要什么。自从有了网联,现在对接方也比较固定了。直接接网联或者微信支付、支付宝支付、拉卡拉…… 他们所需要的要素都差不多。因为它们都要接入网联完成国家监管的需求,所以要素主要看网联需要哪些要素。

当然,它们的签名方式可能会不同;调用的支付渠道地址不同;给支付渠道传递的时候入参组装方式也不同。甚至有的支付渠道还需要有特殊的步骤。这时候怎么抽象呢?

推荐“工作流”+策略模式。这是一种实现积木化的方式。定义一个统一接口,比如

class Executor {

      void execute(Task task);

}

task里放置所有的入参,以及每次执行时产生的,下游需要的中间数据。签名等流程各自实现此接口。这样就实现了自由组装的重用。

举个例子,下面“积木块”各自实现了自己的execute:

微信支付签名、微信支付入参组装、微信支付结果解析、支付宝支付签名、支付宝支付入参组装、支付宝支付结果解析、支付宝特殊处理、下游http调用(这里假设微信和支付宝都是http的post请求来调用的,这样发起调用来说两者只是请求地址和入参不同)

这时候可以组装微信支付流程:

List list = new List();

list.put(微信支付签名);

list.put(微信支付入参组装);

list.put(下游http调用);

list.put(微信支付结果解析);

for(Executor e :list) {

    e.execute(task);

}

同样可以组装支付宝支付流程:

List list = new List();

list.put(支付宝支付签名);

list.put(支付宝支付入参组装);

list.put(下游http调用);

list.put(支付宝支付结果解析);

list.put(支付宝支付特殊处理);

for(Executor e :list) {

    e.execute(task);

}

不同的流程只是list不同,这个list是可以时间配置化的,可以配置在配置文件中、甚至可以从数据库中读取。微信支付流程和支付宝支付流程是两种不同的策略,可以使用策略模式。入参选择哪种策略就用哪种策略执行。这样,各个流程之间没有干扰,积木块变更影响小还可以随意组合灵活性高。

整体重构

朋友的业务复杂性还不在于支付,而在于收单。解决方法就是文章开头提到的接入平台的方式。打造平台的关键不是技术,而是规范。自己制定规范。别人接入都要按照规范来。

这里有前提:公司自身的影响力。平台是底层自己需要有决策权,比如微信开放平台,想接入就要理解并使用他们的API。而因为微信基础在,必须按照人家说的来,这就是平台影响力。

在实际工作中,一般有两种情况。接入方自身也没有什么规范,本身就要求功能可用,这时候咱们自身有规范,对方比较容易接受。另外一种,对方是实力背景的大公司,也有自己的规范。这时候咱们处于弱势,要按照别人的规范来,可以使用上面支付重构的积木化方法进行进行组合。

重构过程与业务支撑之间怎样平衡?

在重构过程中一般会遇到两顶思考帽问题:一顶是需求的帽子,一顶是重构的帽子。有限的时间怎么分配呢?建议一开始就定好目标:什么阶段要重构到什么程度,然后分解工作。最后分摊到每天比如需要2小时时间。那么在需求开发时间评估的时候就要把这个时间扣掉。

重构做完,老逻辑迁移到新逻辑有风险。这时候我的建议是:

首先,把新功能当成重构结果的验金石。有新功能,先在新功能上验证新逻辑的正确性。因为新功能上线到上量有一个过程,初期出了问题影响也不会很大。

然后,老逻辑迁移需要灰度。可以一个业务一个业务的灰度迁移,也可以按照流量百分比进行迁移。

总结

最后总结一下对重构的几点建议:

1、小步快跑,稳步迭代

2、设计与代码的重构结伴而行

3、如果模块或者函数不能想到一个好名字,很可能是设计出了问题

4、每步要保证足够简单,想象随时可能会停止

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值