微信架构 & 支付架构(下)
3. 管理网络请求
首先看看原来 iOS 处理支付网络请求的缺陷:
原来支付的请求,都是通过一个单例网络中心去发起请求,然后收到回包后,通过抛通知,或者调用闭包的方式回调给业务侧。
会存在这样的问题:
1、CGI 一对多通讯问题。
举个之前遇到的问题。
那么钱包发起的 Cgi 的回包就会覆盖收付款页面的数据。之前在 iOS 只能通过修修补补,增加场景值,增加些标记位来解决。可能某一天就会又出现新的坑。
1、进入钱包页面后,发起了一个 Cgi
2、然后进入收付款页面也发起同一个 Cgi.
3、如果收付款发起的回包先到
4、然后钱包首页的回包再到。
5、CGI 生命周期问题。
不时会有用户反馈一下,怎么没有做什么操作,突然就会弹出网络报错。
原因就是 Cgi 的生命周期有问题,在业务结束后,Cgi 的回包仍然得到了处理。
解决方案:
1、将 Cgi 抽象为独立对象
在架构设计上来说,旧架构是通过单例模式实现的集约型 API,而我们新的架构则是通过命令模式实现的离散型 API。
也就是将 Cgi 封装为独立对象。我们把 Cgi 相关属性和能力内聚起来。开发业务时,只需简单继承 BaseCgi,设置一下参数即可。
2、划分职责,明确生命周期
关于 Cgi 由谁发起,之前安卓和 iOS 都没有一个统一的做法。有些人会放到 Activity,ViewController,和 UI 代码耦合起来。
因此,在跨平台软件架构中,我们统一由业务流程 UseCase 进行发起。并且生命周期是一对一的,一个 Cgi 只会有一个 UseCase 处理, UseCase 销毁后,Cgi 也随之销毁。
对比旧架构:
1. 杜绝了一对多通信造成的 Bug
2. 生命周期和业务逻辑绑定,不会出现业务结束,Cgi 回来后再触发动作。
3. 高内聚,低耦合。将 Cgi 相关的数据,能力集中处理,业务侧无需感知。
4. 提供统一的缓存,加密能力。
第一步和第二步,我们抽象了业务流程,加入了路由机制。
在第三步管理网络请求后。我们的软件架构演进为这样子。
4. 规范数据传递
iOS 和安卓的旧架构都存在信息传递不当和数据污染问题。这个问题最严重。iOS 和 安卓都出过不少 bug。
首先我们来看看最近现网出现过的问题:
之前 iOS 出现,不少内部同事,外部的用户都在反馈:进行零钱页后,会无故弹空白框。而支付又和金钱有关,引起用户的恐慌。
具体原因就是:
1. 进入支付首页时,后台返回了数据,然后被写入到一个公共的 Model.
2. 然后进入钱包页,再进入零钱页。这个公共 model 一路被传递过去。
3. 然后零钱页读取了公共 Model 的数据,但是代码无法处理,导致出现了这个让用户恐慌的问题。
除此之外,之前还有有很多发生在安卓,iOS ,像钱包页零钱展示错误。付款的时候。银行卡失效等等问题。
这些问题五花八门,看起来发生的地方,场景都不一样。每次遇到这类问题的时候,就只能去修修补补。
但是深究下去,会发现真正的原因,是软件架构上存在的问题:
支付旧的架构采用了黑板模式,虽然方便了数据读写。但是带来的问题和收益完全不成正比:
1.存在公共读写的数据类型。
安卓传递的数据类型是一个字典,而 iOS 则是一个 Model 对象。所有的界面,业务逻辑都共用一个数据。
2.无序的数据流动。
数据的流动是不可追溯的,数据的修改可以发生在任意使用公共数据的地方。
那么支付跨平台软件架构,为了杜绝这样的问题。我是这么做的:
1. 去掉公共读写的数据类型
2. 传递值类型(Value Type)的数据, 后面流程修改数据时,不影响前面的流程。
3. 单向传递数据,只依赖注入必要数据。
4. 如果数据修改需要通知前序流程,使用代理模式通讯。
规范数据传递后。对比旧架构:
1. 从架构上根本解决了困扰微信支付已久的数据污染的问题。
2. 数据的流动变为单向,数据流动变得可追溯。
前面三步,我们抽象了业务流程,加入了路由机制,统一管理网络请求。
那么规范数据传递后,我们软件架构就演进为这样子。
总结
软件的本质复杂性存在于复杂的业务需求中。而软件架构的本质就是管理复杂性,因此真正的好的架构,正是在复杂的业务需求中反复提炼和总结归纳而来,解决了真正的业务问题,不是空谈。
软件架构除了清理历史旧架构的缺陷,是我们业务开发的基石之外。还能够赋能业务,为业务带来价值。在建立软件架构的基础上,还围绕着软件架构建立起微信支付的跨平台自动化数据上报机制,防重复支付,安全横切等带来巨大业务收益的能力。有机会的话,后面也会进一步编写相关文章和大家交流探讨。
架构是一个不断演进的过程,随着新的支付业务基于跨平台软件架构的不断编写, 我也会对这个架构进行持续的更新迭代。让这个软件架构更贴合微信支付,更加健壮和完整。