微信支付的軟件架構(gòu)也太特么牛逼了吧...
300本計(jì)算機(jī)編程的經(jīng)典書籍下載
AI全套:Python3+TensorFlow打造人臉識(shí)別智能小程序
最新人工智能資料-Google工程師親授 Tensorflow-入門到進(jìn)階
黑馬頭條項(xiàng)目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版
作者:Jack Jiang
來源:cnblogs.com/imstudy/p/12567241.html
作者:Jack Jiang
來源:cnblogs.com/imstudy/p/12567241.html
大綱
背景 線上效果指標(biāo) 什么是軟件架構(gòu) 為什么需要軟件架構(gòu) 從零到一構(gòu)建支付跨平臺(tái)軟件架構(gòu) 1.抽象業(yè)務(wù)流程 2.加入路由機(jī)制 3.管理網(wǎng)絡(luò)請(qǐng)求 4.規(guī)范數(shù)據(jù)傳遞 總結(jié)
背景
iOS 和安卓實(shí)現(xiàn)不一致 容易出 Bug 通過溝通保證不了質(zhì)量 擴(kuò)展性差,無法快速響應(yīng)業(yè)務(wù)需求 需求變更迭代周期長(zhǎng) 數(shù)據(jù)上報(bào)不全面 質(zhì)量保障體系不完善 缺少業(yè)務(wù)及設(shè)計(jì)知識(shí)沉淀 協(xié)議管理松散 缺少統(tǒng)一的自動(dòng)化測(cè)試 用戶體驗(yàn)不一致 比如下圖就是之前安卓和 iOS 沒有統(tǒng)一前的收銀臺(tái)。 
C++ 的跨平臺(tái)框架,并對(duì)核心支付流程進(jìn)行了重構(gòu)。微信支付跨平臺(tái)從 iOS 7.0.4 版本起, 安卓從 7.0.7 版本起全面覆蓋。
線上效果指標(biāo)
Crash 率 上線前后 Crash 率保持平穩(wěn),沒有影響微信穩(wěn)定性,跨平臺(tái)支付無必現(xiàn) Crash,做到了用戶無感知切換。 舉個(gè)例子,大家可以用微信發(fā)一筆紅包,拉起的收銀臺(tái)和支付流程就是由基于C++編寫的跨平臺(tái)代碼所驅(qū)動(dòng)的。 效能提升

以核心支付流程代碼為例,跨平臺(tái)需要 3512 行,iOS 原生需要 6328 行。減少了近 45% 的代碼。
以新需求開發(fā)為例: 7.0.4 版本需求一:收銀臺(tái)改版 7.0.4 版本需求二:簡(jiǎn)化版本收銀臺(tái) 跨平臺(tái)實(shí)現(xiàn):iOS + 安卓 共計(jì) 3 人日,在封板時(shí)間前完成 原生實(shí)現(xiàn):iOS, 安卓封板時(shí)間后一周才基本完成 跨平臺(tái)實(shí)現(xiàn):iOS + 安卓共計(jì) 5 人日,在封板時(shí)間前完成 原生實(shí)現(xiàn):iOS, 安卓封板時(shí)間后一周才基本完成

對(duì)基于 C++ 如何從零到一構(gòu)建跨平臺(tái)框架感興趣的同學(xué),可以在 https://github.com/100mango/zen/blob/master/Qcon2019/%E5%9F%BA%E4%BA%8E%20C%2B%2B%20%E6%9E%84%E5%BB%BA%E5%BE%AE%E4%BF%A1%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%B7%A8%E5%B9%B3%E5%8F%B0%E5%BC%80%E5%8F%91%E6%A1%86%E6%9E%B6.key 下載我在 2019 QCon 廣州站的演講 《基于 C++ 構(gòu)建微信客戶端跨平臺(tái)開發(fā)框架》的 Keynote.
什么是軟件架構(gòu)
MVC,MVVM 等。為什么需要軟件架構(gòu)
從零到一構(gòu)建支付跨平臺(tái)軟件架構(gòu)
C++ 來編寫業(yè)務(wù)代碼,并沒有成熟的架構(gòu)。即使使用 C++ 編寫業(yè)務(wù)邏輯,但都不涉及 UI,不涉及界面的跳轉(zhuǎn)流程。既然業(yè)界沒有一個(gè)成熟的架構(gòu)可借鑒,那么是不是直接把業(yè)界通用的架構(gòu)簡(jiǎn)單套用一下就好?
1. 抽象業(yè)務(wù)流程
MVC 這種架構(gòu)的話,很快代碼會(huì)變得難以維護(hù)。
因此,為了適應(yīng)微信支付流程多,界面跳轉(zhuǎn)復(fù)雜的特點(diǎn)。架構(gòu)抽象的第一步就是將業(yè)務(wù)流程抽象為一個(gè)獨(dú)立的角色 UseCase。同時(shí), 把界面抽象為 UIPage。 一個(gè)大的業(yè)務(wù)流程可以分解為一個(gè)個(gè)小的業(yè)務(wù)流程。

業(yè)務(wù)流程的代碼能夠聚合到 UseCase 中,而不是分散到原來 iOS, 安卓的各個(gè) ViewController,Activity 中。 業(yè)務(wù)流程和界面得到了復(fù)用。 契合微信支付多流程,界面跳轉(zhuǎn)復(fù)雜的業(yè)務(wù)特點(diǎn)。
2. 加入路由機(jī)制
既然流程得到了抽象,這個(gè)時(shí)候需要針對(duì)業(yè)務(wù)流程做更深的思考。在開發(fā)支付業(yè)務(wù)流程時(shí),開發(fā)者不可繞過的問題有:
流程之間,頁(yè)面之間的流傳。 
比如我們要給一個(gè)朋友轉(zhuǎn)賬,輸入金額,確認(rèn)支付,觸發(fā) Cgi 后。下一個(gè)流程是多變的。有可能用戶需要去實(shí)名,有可能用戶要進(jìn)入一個(gè)安全攔截的 WebView,或者是正常拉起收銀臺(tái)。
本文中的名詞 CGI可以理解為一個(gè)網(wǎng)絡(luò)請(qǐng)求,類似HTTP請(qǐng)求。那么以往在 iOS, 安卓分開實(shí)現(xiàn)時(shí),都沒有一個(gè)統(tǒng)一的處理機(jī)制。要么就是通過網(wǎng)絡(luò)回包的某個(gè)字段來判斷,要么就是本地維護(hù)一些狀態(tài)來決定下一步走什么流程等等。非常繁瑣,易錯(cuò)。 特殊流程的處理

支付業(yè)務(wù)流程還有個(gè)特殊的地方,那就是在正常流程的中間,往往很多時(shí)候要需要插入一些特殊流程。比如有些地方要跳轉(zhuǎn) Webview, 有些地方要跳轉(zhuǎn)小程序,有些地方要彈窗告知用戶風(fēng)險(xiǎn),或者終止當(dāng)前流程,等等。我們經(jīng)常需要在業(yè)務(wù)代碼里面不斷重復(fù)增加這樣的處理。
這些問題,引導(dǎo)我想到,微信支付需要一個(gè)路由機(jī)制。
首先了解一下路由機(jī)制。

結(jié)合微信支付和網(wǎng)絡(luò)密切相關(guān)的特點(diǎn)。創(chuàng)新地將支付領(lǐng)域模型作為傳遞的數(shù)據(jù)。




統(tǒng)一了流程,頁(yè)面的流轉(zhuǎn)。清晰,易維護(hù)。 統(tǒng)一了特殊流程的處理,減少重復(fù)工作。 在加入路由機(jī)制的時(shí)候,結(jié)合微信支付和網(wǎng)絡(luò)密切相關(guān)的特點(diǎn)進(jìn)行了支付領(lǐng)域建模。支付后臺(tái)協(xié)議重構(gòu) 2.0 的核心思想也是圍繞著這個(gè)路由機(jī)制展開。

再來看一下,加入路由機(jī)制后,對(duì)生產(chǎn)力的提升。以支付流程打開 WebView, 小程序?yàn)槔?,減少將近 83% 的代碼。更重要的是,這里的特殊流程,是在路由機(jī)制里面統(tǒng)一處理的,沒有耦合到業(yè)務(wù)代碼中,并且是可復(fù)用的。
3. 管理網(wǎng)絡(luò)請(qǐng)求

CGI 一對(duì)多通訊問題。 舉個(gè)之前遇到的問題。 
那么錢包發(fā)起的 Cgi 的回包就會(huì)覆蓋收付款頁(yè)面的數(shù)據(jù)。之前在 iOS 只能通過修修補(bǔ)補(bǔ),增加場(chǎng)景值,增加些標(biāo)記位來解決。可能某一天就會(huì)又出現(xiàn)新的坑。
進(jìn)入錢包頁(yè)面后,發(fā)起了一個(gè) Cgi 然后進(jìn)入收付款頁(yè)面也發(fā)起同一個(gè) Cgi. 如果收付款發(fā)起的回包先到 然后錢包首頁(yè)的回包再到。
CGI 生命周期問題。

不時(shí)會(huì)有用戶反饋一下,怎么沒有做什么操作,突然就會(huì)彈出網(wǎng)絡(luò)報(bào)錯(cuò)。 原因就是 Cgi 的生命周期有問題,在業(yè)務(wù)結(jié)束后,Cgi 的回包仍然得到了處理。
將 Cgi 抽象為獨(dú)立對(duì)象 在架構(gòu)設(shè)計(jì)上來說,舊架構(gòu)是通過單例模式實(shí)現(xiàn)的集約型 API,而我們新的架構(gòu)則是通過命令模式實(shí)現(xiàn)的離散型 API。 也就是將 Cgi 封裝為獨(dú)立對(duì)象。我們把 Cgi 相關(guān)屬性和能力內(nèi)聚起來。開發(fā)業(yè)務(wù)時(shí),只需簡(jiǎn)單繼承 BaseCgi,設(shè)置一下參數(shù)即可。 
劃分職責(zé),明確生命周期
關(guān)于 Cgi 由誰(shuí)發(fā)起,之前安卓和 iOS 都沒有一個(gè)統(tǒng)一的做法。有些人會(huì)放到 Activity,ViewController,和 UI 代碼耦合起來。
因此,在跨平臺(tái)軟件架構(gòu)中,我們統(tǒng)一由業(yè)務(wù)流程 UseCase 進(jìn)行發(fā)起。并且生命周期是一對(duì)一的,一個(gè) Cgi 只會(huì)有一個(gè) UseCase 處理, UseCase 銷毀后,Cgi 也隨之銷毀。

杜絕了一對(duì)多通信造成的 Bug 生命周期和業(yè)務(wù)邏輯綁定,不會(huì)出現(xiàn)業(yè)務(wù)結(jié)束,Cgi 回來后再觸發(fā)動(dòng)作。 高內(nèi)聚,低耦合。將 Cgi 相關(guān)的數(shù)據(jù),能力集中處理,業(yè)務(wù)側(cè)無需感知。 提供統(tǒng)一的緩存,加密能力。

第一步和第二步,我們抽象了業(yè)務(wù)流程,加入了路由機(jī)制。

在第三步管理網(wǎng)絡(luò)請(qǐng)求后。我們的軟件架構(gòu)演進(jìn)為這樣子。

4. 規(guī)范數(shù)據(jù)傳遞
之前 iOS 出現(xiàn),不少內(nèi)部同事,外部的用戶都在反饋:進(jìn)行零錢頁(yè)后,會(huì)無故彈空白框。而支付又和金錢有關(guān),引起用戶的恐慌。在公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師后臺(tái)回復(fù):2T,可以獲取架構(gòu)師視頻整套系統(tǒng)教程。
00:07

進(jìn)入支付首頁(yè)時(shí),后臺(tái)返回了數(shù)據(jù),然后被寫入到一個(gè)公共的 Model. 然后進(jìn)入錢包頁(yè),再進(jìn)入零錢頁(yè)。這個(gè)公共 model 一路被傳遞過去。 然后零錢頁(yè)讀取了公共 Model 的數(shù)據(jù),但是代碼無法處理,導(dǎo)致出現(xiàn)了這個(gè)讓用戶恐慌的問題。

存在公共讀寫的數(shù)據(jù)類型。 安卓傳遞的數(shù)據(jù)類型是一個(gè)字典,而 iOS 則是一個(gè) Model 對(duì)象。所有的界面,業(yè)務(wù)邏輯都共用一個(gè)數(shù)據(jù)。 無序的數(shù)據(jù)流動(dòng)。 數(shù)據(jù)的流動(dòng)是不可追溯的,數(shù)據(jù)的修改可以發(fā)生在任意使用公共數(shù)據(jù)的地方。
那么支付跨平臺(tái)軟件架構(gòu),為了杜絕這樣的問題。我是這么做的:

去掉公共讀寫的數(shù)據(jù)類型 傳遞值類型(Value Type)的數(shù)據(jù), 后面流程修改數(shù)據(jù)時(shí),不影響前面的流程。 單向傳遞數(shù)據(jù),只依賴注入必要數(shù)據(jù)。 如果數(shù)據(jù)修改需要通知前序流程,使用代理模式通訊。
從架構(gòu)上根本解決了困擾微信支付已久的數(shù)據(jù)污染的問題。 數(shù)據(jù)的流動(dòng)變?yōu)閱蜗?,?shù)據(jù)流動(dòng)變得可追溯。


總結(jié)
看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人
往期資源:
