餓了麼移動APP的架構演進

1MVC編程

咱們常說,脫離業務談架構就是純粹的耍流氓。餓了麼移動APP的發展也是其業務發展的一面鏡子。服務器

 

在餓了麼業務發展的早期,移動APP經歷了從無到有的階段。爲了快速上線搶佔市場,傳統移動APP開發的MVC架構成了「短平快」思路的首選:網絡


MVC架構數據結構

 

這種架構因簡單清晰,容易開發而被大多數人所接受。架構

在MVC的體系架構中,Controller層負責整個APP中主要邏輯功能的實現;Model層則負責數據結構的描述以及數據持久化的功能;而View層做爲展示層負責渲染整個APP的UI。分工清晰,簡潔明瞭。框架

此外,這種系統架構在語言框架層就獲得了Apple的支持,因此很是適用於APP的startup開發。工具

而後,這種架構在開發的後期會因爲其超高耦合性,形成Controller層龐大,而這也是一直被人們所詬病。最終的MVC都從Model-View-Controller走向了Massive-View-Controller的終點。組件化

 

2性能

Module動畫

Decoupled

 

「短平快」的MVC架構在早期能夠知足餓了麼移動APP的快速開發迭代,可是隨着代碼量的不斷增長,臃腫的Controller層也在漸露頭角;而業務上,餓了麼移動APP也從單一APP發展爲多APP齊頭並進的格局。這時候,下降耦合,複用已有模塊便成了架構的第一要務。

架構中,模塊複用的第一要求即是代碼的功能組件化。組件化意味着擁有獨立功能的代碼從系統中進行抽象並剝離,再以「插件」的形式插回原有系統中。這樣剝離出來的功能組件,即可以供其餘APP使用,從而下降系統中模塊與模塊之間的耦合性;

也同時提升了APP之間代碼的複用性。

餓了麼移動對於組件有兩種定義:公有組件和業務組件。公有組件指的是封裝得比較好的一些SDK,包括一些第三方組件和本身內部使用的組件。如iOS中最著名的網絡SDK AFNetworking,Android下OKHttp,都是這類組件的表明。

業務組件,則定義爲包含了一系列業務功能的總體,例如登陸業務組件,註冊業務組件,即爲此類組件的典型表明。

對於公有組件,餓了麼移動採起了版本化的管理方式,而這在iOS和Android平臺上早有比較成熟的解決方案。例如,對於iOS平臺,CocoaPods基本上成爲了代碼組件化管理的標配;在Android平臺上,Gradle也是很是成熟和穩健的方案。

採用以上管理工具的另外一個緣由在於,對企業開發而言,代碼也是一種商業機密。基於保密的目的,支持內網搭建私有服務器成爲了必需。以上的管理工具都可以很好地支持這些操做。

對於業務的組件化,咱們採起了業務模塊註冊機制來達到解耦合的目的。每一個業務模塊對外提供相應的業務接口,同時在系統啓動的時候向Excalibur系統註冊本身模塊的Scheme(Excalibur是餓了麼移動用來保存Scheme與模塊之間映射的系統,同時能根據Scheme進行Class反射返回)。 當其餘業務模塊對該業務模塊有依賴時,從Excalibur系統中獲取相關實例,並調用相應接口來實現調用,從而實現了業務模塊之間的解耦目的。

而在業務組件,即業務模塊的內部,則能夠根據不一樣開發人員的偏好,來實現不一樣的代碼架構。如如今討論得比較火的MVVM, MVP等,均可以在模塊內部進行而不影響總體系統架構。

 

這時候的架構看起來更像是這樣:

 

EMC架構

 

E(Excalibur)M(Modules)C(Common)架構以高內聚、低耦合爲主要的特色,以面向接口編程爲出發點,下降了模塊與模塊之間的聯繫。

該架構的另一大好處則在於解決了不一樣系統版本的兼容性問題。這裏以iOS平臺下的WebView做爲例子來進行說明。Apple從iOS8系統開始提供了一套更好的Web支持框架——WebKit,但在iOS7系統下卻沒法兼容,從而致使Crash。

使用此類架構,能夠在iOS7系統下仍然註冊使用傳統的WebView來渲染網頁,而在iOS8及其以上系統註冊WebKit來做爲渲染網頁的內核。既避免了Apple嚴格的審覈機制,又達到了動態加載的目的。

 

 

3Hybrid

移動APP的開發有兩種不一樣的路線,NativeAPP和Web APP。這兩種路線的區別相似於PC時代開發應用程序時的C/S架構和 B/S架構。

以上咱們談到的都屬於典型的Native APP,即全部的程序都由本地組件渲染完成。這類APP優勢是顯而易見的,渲染速度快、用戶體驗好;缺點同時也十分突出:出現了錯誤必定要等待下一次用戶進行APP更新纔可以修復。

Web APP的優勢剛好就是Native APP的缺點所在,其頁面所有采用H5撰寫並存放在服務器端。每次進行頁面渲染時都從服務器請求最新的頁面。一旦頁面有錯誤,服務器端進行更新便能馬上解決。

不過其弊端也容易窺見:每次頁面都須要請求服務器,形成渲染時等待時間過長,從而致使的用戶體驗不夠完美,而且性能上較Native APP慢了1-2個數量級;與此同時還會致使更多的用戶流量消耗。

另外一個缺點則在於,Web APP在移動端上調用本地的硬件設備存在必定的不便。不過這些弊端也都有相應的解決方案,如PhoneGap將網頁提早打包在本地以減小網絡的請求時間;同時也提供一系列的插件來訪問本地的硬件設備。

然而,儘管如此,其渲染速度上仍是存在必定的差距。

Hybrid APP則是綜合了兩者優缺點的解決方案。餓了麼移動對於此二類APP的觀點在於,純粹展現性的模塊會更適合使用Web頁面來達到渲染的目的;而更多的數據操做性、動畫渲染性的模塊則更適合採用Native的方式。

基於以前的EMC架構,咱們將部分模塊從新進行了架構:

 

Hybrid EMC架構

Hybrid-EMC架構中,Web做爲一個子模塊,註冊加入到整個系統中,從而讓業務上須要快速迭代的模塊實現實時更新。

 

4

React-Native& Hot Patch

通過這些年的業務發展,Hybrid提供的展現界面更新方案也逐漸地沒法知足APP更新迭代的須要。所以愈來愈多動態部署的方案被提了出來,好比iOS下的JSPatch, waxPatch,Android下的Dexpose, AndFix, ClassLoader,都是比較成熟Hot Patch動態部署解決方案。

這些方案的思路都是經過下載遠程服務器的代碼來動態更新本地的代碼行爲。

React-Native則屬於另外一種動態部署的方案,其核心原理在於經過JavaScript來調用本地組件進行界面的渲染。

而餓了麼移動APP發展到今天,各個APP綜合用戶量已通過億。所以一個很是小的Bug所帶來的問題均可能會直接影響到幾萬人的使用。爲了保證APP的穩定性和健壯性,Hot Patch方案也就成了當下最有待解決的問題。

根據80%的用戶訪問20%頁面這一80/20原則,保證這20%訪問最頻繁的頁面的穩定性就是保證了80%的APP的穩定性。所以,餓了麼移動對於部分訪問最頻繁的模塊進行了React-Native備份。

當這部分頁面出現問題時,APP能夠經過服務器的配置,自動切換成React-Native的備份頁面;而與此同時開發人員開發一個小而精的Hot Patch來修復出現的問題。當Hot Patch完成修補後,再切換回Native APP的原生功能。

 

這時候的架構看起來會像是這樣:

HotPatch-EMC架構

 

HotPatch-EMC的架構主要目標在於解決移動APP的穩定性問題。經過RN與Native的主備,能夠減小系統APP出錯帶來的失誤。

相關文章
相關標籤/搜索