App的業務發展和架構演進
一、業務發展
App剛好發布了52個版本,大概歸為6類。
1、課程 (課程展示,視頻播放、視頻緩存、音頻播放、音頻緩存)
2、題庫 (各種類型的試卷、答題、試卷附屬功能、疑問分析、收藏、錯題鞏固·····)
3、班級(購課自動進班、聊天、消息推送)
4、個性化 (每周任務)
5、課程展示和購買
6、臨時性功能(進班進組、推薦有獎、B豆餘額、收貨地址管理)
二、過去的架構
當業務在瘋狂發展,需求在快速的變化,架構也變得更加的複雜。說到框架,相信大家在縱向上都會按照UI層-網路層-持久層-系統框架來分層,看上去似乎沒有什麼問題。橫向業務上大家想必也儘可能按照模塊劃分了,但是由於App的獨特性,大部分模塊還是以頁面為主。那麼隨著業務發展,業務邊界慢慢變得模糊,跳轉邏輯慢慢變得複雜,如果不好好處理,那麼橫向業務模塊就會像融化的巧克力一樣,不分你我。
存在的問題:
1、模塊劃分不明確,相同職責的代碼散落各處,重用性不夠:代表的例子有試卷下面的疑問分析
2、頁面數據耦合性強,B頁面的數據,部分來至A頁面,這樣C頁面無法直接跳轉到B頁面。
3、各個組件,各個頁面之間的跳轉邏輯關聯性越來越多,相互間的依賴也就更多,拔起蘿蔔帶出泥。
4、組件和頁面的調用中需要鑒權或者token機制不能統一管理
三、解決方案
1、兩個契機:
早在我們做『消息推送』的時候,我們就有了『動態跳轉』的需求:在任何非考試、非視頻頁面收到消息,頁面顯示彈框,點擊跳轉到直播、回放、錄播、閱讀、音頻等頁面,於是我們制定了一份《Sierra App消息通知協議》 , 這份協議有很多欄位,這裡重點提三個與本文相關的:
動作的唯一標識
target:sierra://course
# 跳轉到課程頁面
target:sierra://course/micro
# 跳轉到微課
target:sierra://webview
# 跳轉到網頁
目標動作的所需參數 ,與target密切相關
for target:sierra://courseextra:courseId:567
for target:sierra://webviewextra:url:https://www.btclass.cn
UI展示參數,該參數與以上兩個參數完全沒有關係
『Web與Native的交互』,就以現在B豆充值功能為例子,Web需要調用Native的支付功能、分享功能,跳轉到首頁的功能,先說交互原理大致如下:
iOS :使用WebViewJavascriptBridge,提供方法供H5調用,本質是攔截iframe的請求,同時由WebViewJavascriptBridge來規範通訊規則。H5調用成功會得到返回結果「callSuccess」,失敗會得到「callFail」
·····················
Android :使用了addJavascriptInterface方法來注入一個AndroidJS對象,可供H5直接調用。
Android調用H5方法 統一使用JsBridge.方法名
······················
Web:對於Android,可以直接獲取AndroidJS對象調用方法(參數中的對象轉成JSON字元串)。
對於iOS,可以通過WebViewJavascriptBridge,調用方法。
再看《Sierra-App H5與Native交互協議》 ,主要分為兩種類型Action And Jump:
普通動作,比如分享
跳轉動作,比如跳轉到首頁
2、呼之欲出的統一:路由
回到我們之前的問題,頁面、組件之間複雜的跳轉、調用、依賴,完全就是『高耦合、低內聚』
這裡所說的並不是傳統意義上的路由,而是更簡單的用Target-Action來形容更合適。
組件(模塊)化的方案遠不止這一種,可謂神仙打架,以下是各家的方案
iOS應用架構談 組件化方案
蘑菇街 App 的組件化之路
蘑菇街 App 的組件化之路·續
iOS 組件化方案探索
天貓之解耦神器 —— 統跳協議和Rewrite引擎
iOS 組件化 —— 路由設計思路分析
路由能做的事很多很多····比如以下摘自iOS 組件化 —— 路由設計思路分析
1、3D-Touch功能或者點擊推送消息,要求外部跳轉到App內部一個很深層次的一個界面。比如微信的3D-Touch可以直接跳轉到「我的二維碼」。「我的二維碼」界面在我的裡面的第三級界面。或者再極端一點,產品需求給了更加變態的需求,要求跳轉到App內部第十層的界面,怎麼處理?2、自家的一系列App之間如何相互跳轉?如果自己App有幾個,相互之間還想相互跳轉,怎麼處理?3、如何解除App組件之間和App頁面之間的耦合性?隨著項目越來越複雜,各個組件,各個頁面之間的跳轉邏輯關聯性越來越多,如何能優雅的解除各個組件和頁面之間的耦合性?4、如何能統一iOS和Android兩端的頁面跳轉邏輯?甚至如何能統一三端的請求資源的方式?項目裡面某些模塊會混合ReactNative,Weex,H5界面,這些界面還會調用Native的界面,以及Native的組件。那麼,如何能統一Web端和Native端請求資源的方式?5、如果使用了動態下發配置文件來配置App的跳轉邏輯,那麼如果做到iOS和Android兩邊只要共用一套配置文件?6、如果App出現bug了,如何不用JSPatch,就能做到簡單的熱修復功能?比如App上線突然遇到了緊急bug,能否把頁面動態降級成H5,ReactNative,Weex?或者是直接換成一個本地的錯誤界面?7、如何在每個組件間調用和頁面跳轉時都進行埋點統計?每個跳轉的地方都手寫代碼埋點?利用Runtime AOP ?8、如何在每個組件間調用的過程中,加入調用的邏輯檢查,令牌機制,配合灰度進行風控邏輯?9、如何在App任何界面都可以調用同一個界面或者同一個組件?只能在AppDelegate裡面註冊單例來實現?比如App出現問題了,用戶可能在任何界面,如何隨時隨地的讓用戶強制登出?或者強制都跳轉到同一個本地的error界面?或者跳轉到相應的H5,ReactNative,Weex界面?如何讓用戶在任何界面,隨時隨地的彈出一個View?
四、動態化
在App完成了組件化和模塊化之後,在路由的幫助下,App已經可以實現動態安全的跳轉,但我們需要更加的動態化, 概括上來說:硬的更硬,軟的更軟,軟硬結合。
1、硬的更硬
首先對於用戶經常使用,需求穩定的功能比如視頻、音頻、考試等硬核功能,要讓它們像一顆石頭一樣,穩定、可靠。PS:題庫可以抽象後重新整理功能
2、軟的更軟
讓App一些頁面變得更軟,更動態,比如首頁、課程詳情等頁面。目的只有一個,滿足運營和業務的需求,同時不影響原來的硬功能。方案非常多,可謂八仙過海各顯神通。
配置化:簡單來說通過動態下發配置文件,App端構件渲染引擎來渲染視圖
PS:其實我們的消息中心就是根據樣式由後台的style欄位來顯示的
有贊 App 動態化配置中心實踐
天貓App的動態化配置中心實踐
天貓APP改版之全新大首頁架構&開發模式全面升級-TAC
貓客頁面內組件的動態化方案-Tangram 2.0
美團Picasso 開啟大前端的未來
美團移動端動態化實踐
Hybird化:目前我們在App中接入了不少的功能是用Web來實現的,比如推薦有獎,B豆管理,發書活動,進班進組。Web有一個優勢就是可以同時在微信和App同時運行,便於推廣。
完全動態化:
美團Picasso 開啟大前端的未來
滴滴 iOS 動態化方案 DynamicCocoa 的誕生與起航
貓客頁面內組件的動態化方案-Tangram 2.0
阿里無線11.11 : Weex——關於移動端動態性的思考、實現和未來
移動動態化方案在蜂鳥的架構演進(含React Native與Weex對比)
強無敵:微信小程序
3、軟硬結合
上面說了那麼多動態化的方案,那到底哪個適合我們呢?歡迎大家討論,這裡我僅表達下我觀點:
1、原有的硬功能不要放棄,而應該優化體驗到極致。
2、首頁使用web或者配置化,更動態的滿足運營業務需求,比如隨時增加活動入口,課程音頻入口等等。
3、路由將作為App的中心管理器,管理頁面組件之間的邏輯,同時負責鑒權等操作。
TAG:BT學院技術產品團隊 |