微信支付在各個操做系統,各個應用下的挑戰仍是蠻大的,這也得益於騰訊架構師的專業。程序員
做爲一個重要業務,微信支付在客戶端上面臨着各類問題,其中最核心問題就是分平臺實現致使的問題。小程序
容易出 Bug緩存
經過溝通保證不了質量安全
需求變動迭代週期長微信
數據上報不全面網絡
缺乏業務及設計知識沉澱閉包
協議管理鬆散架構
缺乏統一的自動化測試app
-
好比下圖就是以前安卓和 iOS 沒有統一前的收銀臺
爲了解決分平臺實現這個核心問題,並解決以往的技術債務。咱們創建起了一整套基於 C++ 的跨平臺框架,並對核心支付流程進行了重構。框架
微信支付跨平臺從 iOS 7.0.4 版本起, 安卓從 7.0.7 版本起全面覆蓋。
線上效果指標
以 iOS 上線狀況爲例:
②效能提高
7.0.4 版本需求一:收銀臺改版。
7.0.4 版本需求二:簡化版本收銀臺。
什麼是軟件架構
什麼是軟件架構?正如 Ivar Jacobson (UML 之父)說過的同樣,找五我的來回答這個問題,五我的可能都有各自不一樣的答案。
架構定義能夠有不少種說法,從代碼規範到發佈流程均可以是架構的一部分。
針對微信支付的業務特色,這裏對架構的定義是:架構是系統的組成部件及其之間的相互關係(通信方式)。
這更符合咱們程序員平常編寫業務代碼時對架構的理解。也就是通俗意義上講的 MVC,MVVM 等。
爲何須要軟件架構
早在 1986 年的時候,人月神話的做者在討論軟件的複雜性時,談到:軟件的本質複雜性存在於複雜的業務需求中。
而管理複雜性,最根本的手段就是職責分離。爲了實現職責分離,代碼重用,架構慢慢地復現出來。架構的本質是管理複雜性。
沒有架構,咱們全部的代碼都耦合在一塊兒,人類的心智模型不擅長處理這種複雜性,架構的設立,和圖書館的圖書分類,公司的組織劃分等,本質都是同樣的。是爲了管理複雜性,以取得更高的生產力。
從 0 到 1 構建支付跨平臺軟件架構
在移動客戶端領域,業界基於 C++ 來編寫業務代碼,並無成熟的架構。即便使用 C++ 編寫業務邏輯,但都不涉及 UI,不涉及界面的跳轉流程。
既然業界沒有一個成熟的架構可借鑑,那麼是否是直接把業界通用的架構簡單套用一下就好?
抽象業務流程
如今業界通用的有 MVC,MVP,MVVM 。這些你們都熟悉的軟件架構。可是這些軟件架構都存在一個問題: 那就是沒有處理好業務流程, 界面轉場。
微信支付的流程多。而流程就是由一個個的界面(ViewController,Activity)和相關的業務邏輯組合而成。
上面的 MV(X)模式忽略了一個很是重要的一點,那就是業務流程,界面的轉場究竟由誰負責。
也即 ViewController 與 ViewController 之間的關係由誰維護,業務流程的邏輯寫在哪裏。
若是還按照傳統的 MVC 模式,那麼 ViewController 本身負責和不一樣的 ViewController 通信。
那麼 ViewController 得不到複用,更致命的是業務流程的代碼很是不清晰,業務流程的代碼都被分散到各個 Controller 中, 而一個 Controller 又可能耦合了多個業務的代碼。
舉個例子:一個普通的轉帳流程,可能會涉及風控攔截,實名驗證, 收銀臺, 綁卡,支付成功頁等等。
所以,爲了適應微信支付流程多,界面跳轉複雜的特色。架構抽象的第一步就是將業務流程抽象爲一個獨立的角色 UseCase。
和剛纔基於 MVC 混亂的架構相比:
業務流程的代碼可以聚合到 UseCase 中,而不是分散到原來 iOS,安卓的各個 ViewController,Activity 中。
業務流程和界面獲得了複用。
契合微信支付多流程,界面跳轉複雜的業務特色。
加入路由機制
既然流程獲得了抽象,這個時候須要針對業務流程作更深的思考。在開發支付業務流程時,開發者不可繞過的問題有:
①流程之間,頁面之間的流傳
②特殊流程的處理
路由機制的核心思想,就是經過向路由傳遞數據,而後路由解析數據,並響應。
那麼怎麼創建這個支付領域模型的呢?建模,就是創建映射。領域知識+建模方法=領域建模。那麼這裏的領域知識,就是對支付業務流程的理解。
首先,微信支付業務特色就是和網絡密切相關,流程和頁面每每是由 CGI 串聯起來。
所以創建模型時,最外層即是網絡回包。對於路由機制,這裏咱們只關心路由數據模型。
路由數據模型由路由類型,還有各個路由類型所須要的信息組合成。路由類型清晰的定義了要觸發的行爲。
到底是要開啓一個 UseCase,仍是要打開一個界面,或者 網頁,小程序,彈窗等等。
創建支付領域模型後,咱們路由的解析就變得很是清晰了。路由解析以後,會根據路由類型,觸發不一樣的動做。
好比流程,界面流轉,會交給 UseCase 處理。而特殊流程,好比打開小程序,打開 WebView,彈窗這些行爲會統一進行處理。
加入路由機制後,對比 iOS,安卓原來的舊架構:
統一了流程,頁面的流轉。清晰,易維護。
統一了特殊流程的處理,減小重複工做。
-
在加入路由機制的時候,結合微信支付和網絡密切相關的特色進行了支付領域建模。支付後臺協議重構 2.0 的核心思想也是圍繞着這個路由機制展開。
再來看一下,加入路由機制後,對生產力的提高。以支付流程打開 WebView, 小程序爲例,減小將近 83% 的代碼。
更重要的是,這裏的特殊流程,是在路由機制裏面統一處理的,沒有耦合到業務代碼中,而且是可複用的。
管理網絡請求
原來支付的請求,都是經過一個單例網絡中心去發起請求,而後收到回包後,經過拋通知,或者調用閉包的方式回調給業務側。
會存在這樣的問題:
舉個以前遇到的問題:
②CGI 生命週期問題
不時會有用戶反饋一下,怎麼沒有作什麼操做,忽然就會彈出網絡報錯。緣由就是 CGI 的生命週期有問題,在業務結束後,CGI 的回包仍然獲得了處理。
解決方案以下:
①將 CGI 抽象爲獨立對象
在架構設計上來講,舊架構是經過單例模式實現的集約型 API,而咱們新的架構則是經過命令模式實現的離散型 API。
所以,在跨平臺軟件架構中,咱們統一由業務流程 UseCase 進行發起。而且生命週期是一對一的,一個 CGI 只會有一個 UseCase 處理, UseCase 銷燬後,CGI也隨之銷燬。
對比舊架構:
杜絕了一對多通訊形成的 Bug。
生命週期和業務邏輯綁定,不會出現業務結束,CGI 回來後再觸發動做。
高內聚,低耦合。將 CGI 相關的數據,能力集中處理,業務側無需感知。
-
提供統一的緩存,加密能力。
在第三步管理網絡請求後,咱們的軟件架構演進爲這樣子:
規範數據傳遞
iOS 和安卓的舊架構都存在信息傳遞不當和數據污染問題。這個問題最嚴重。iOS 和 安卓都出過很多 Bug。
具體緣由就是:
進入支付首頁時,後臺返回了數據,而後被寫入到一個公共的 Model。
而後進入錢包頁,再進入零錢頁。這個公共 Model 一路被傳遞過去。
而後零錢頁讀取了公共 Model 的數據,可是代碼沒法處理,致使出現了這個讓用戶恐慌的問題。
除此以外,以前還有有不少發生在安卓,iOS ,像錢包頁零錢展現錯誤。付款的時候銀行卡失效等等問題。
這些問題五花八門,看起來發生的地方,場景都不同。每次遇到這類問題的時候,就只能去修修補補。
支付舊的架構採用了黑板模式,雖然方便了數據讀寫。可是帶來的問題和收益徹底不成正比:
存在公共讀寫的數據類型。安卓傳遞的數據類型是一個字典,而 iOS 則是一個 Model 對象。全部的界面,業務邏輯都共用一個數據。
-
無序的數據流動。 數據的流動是不可追溯的,數據的修改能夠發生在任意使用公共數據的地方。
那麼支付跨平臺軟件架構,爲了杜絕這樣的問題我是這麼作的:
去掉公共讀寫的數據類型。
傳遞值類型(Value Type)的數據, 後面流程修改數據時,不影響前面的流程。
單向傳遞數據,只依賴注入必要數據。
若是數據修改須要通知前序流程,使用代理模式通信。
規範數據傳遞後,對比舊架構:
從架構上根本解決了困擾微信支付已久的數據污染的問題。
數據的流動變爲單向,數據流動變得可追溯。
總結
軟件的本質複雜性存在於複雜的業務需求中。而軟件架構的本質就是管理複雜性,所以真正的好的架構,正是在複雜的業務需求中反覆提煉和總結概括而來,解決了真正的業務問題,不是空談。
軟件架構除了清理歷史舊架構的缺陷,是咱們業務開發的基石以外。還可以賦能業務,爲業務帶來價值。
在創建軟件架構的基礎上,還圍繞着軟件架構創建起微信支付的跨平臺自動化數據上報機制,防重複支付,安全橫切等帶來巨大業務收益的能力。有機會的話,後面也會進一步編寫相關文章和你們交流探討。
架構是一個不斷演進的過程,隨着新的支付業務基於跨平臺軟件架構的不斷編寫, 我也會對這個架構進行持續的更新迭代。讓這個軟件架構更貼合微信支付,更加健壯和完整。
做者:方秋枋
編輯:陶家龍
出處:《基於 C++ 構建微信客戶端跨平臺開發框架》
若是文章對您有幫助,請您分享、點贊、在看,一波三連支持一下做者,很是感謝!
本文分享自微信公衆號 - Java學習指南(gh_85b94beaede2)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。