天天看點

App用戶端架構演化之路

2015年入職XDF參與留留學iOS端的研發,至今,參與了好幾個項目(留留學、掌上新東方、SL、樂聽說等),最近負責樂聽說iOS App端。不同項目的經曆,讓我接觸到了不同的項目架構和代碼風格,也讓我對App的項目架構有所思考與心得。

1、App早期架構1.0

2015年6月留留學App iOS端1.0.0版本誕生,當時采用的架構很簡單,就是在傳統的MVC架構基礎上,封裝了一個網絡服務層建構而成的,當時為了快速疊代上線,是以移動端App開發采用了“短平快”的MVC架構,架構如下圖所示:

App用戶端架構演化之路

這種架構以層次結構簡單清晰,代碼容易開發而被大多數人接受,各層的分工如下:

  • View層:顯示層,負責UI的渲染。
  • Controller層:作為View層和Service層中間層對上提供資料給View層展示,對下負響應使用者的互動。
  • Service層:業務層,負責APP業務邏輯封裝,如預約課程等業務邏輯,對上層提供業務封裝後的接口。
  • Modle層:資料層,負責資料的包裝、整理、解析等。
  • mPass層:主要負責提供一些底層的功能支援,如資料庫、拍照、分享等。

但經過幾個版本的疊代,我們發現App所采用的MVC架構從Model-View-Controller走向了Massive-View-Controller的終點,其最嚴重的結果就是Control層的代碼越來越多越來越臃腫難于擴充維護,同時Control層和View層之間存在一些較高的耦合。

這種架構在開發的後期會由于其超高耦和性,進而造就龐大Controller層,而這也是一直被人所诟病。

2、App架構2.0

基于上述遇到的問題,我們對原有的傳統架構做了優化和調整,提出App架構2.0,并在留留學2.3.0項目中開始逐漸重構采用MVVM分層架構,通過MVVM架構,可以有效實作Controller和View的解耦,同時使Controller輕量級,最終使越來越臃腫的Controller層逐漸縮小并分解解耦,業務邏輯分子產品下沉。

我參與的三個項目都是基于MVVM架構,包括:留留學App2.3.0,掌上新東方App等項目,現在以留留學、掌上新東方為例,留留學調整後的架構如下:

App用戶端架構演化之路

掌新架構如下:

App用戶端架構演化之路

各層的分工如下:

  • View層:顯示層,負責UI的渲染。
  • Controller層:作為View層和ViewModel層中間層對上提供資料給View層展示,對下負響應使用者的互動。
  • ViewModle層:把原來ViewController層的業務邏輯和頁面邏輯等剝離出來放到ViewModel層。
  • Modle層:資料層。
  • mPass層:主要負責提供一些底層的功能支援,如資料庫、拍照、分享等。

通過MVVM架構,可以有效實作Controller和View的解耦,同時使Controller輕量級,但這種架構也有一些弊端,會讓導緻VM或Model中出現大量的基本業務處理、資料處理等,最後也會導緻VM層變的臃腫,同時讓Model層沒那麼純粹,變的雜亂無序,是以還是需要進一步優化和剝離業務與資料的耦合。

3、App架構2.0+

也基于上述遇到的問題,我們對App架構2.0做了優化和調整,便衍生了App2.0+分層架構,采用MVVM+分層架構模式解耦,使越來越臃腫的Controller層逐漸縮小并分解解耦,業務邏輯分子產品下沉。由于留留學3.1.0之後就暫停了疊代,是以隻對掌上新東方App 3.1.0之後的版本開始逐漸采用MVVM+分層架構模式進一步解耦。調整後的架構如下:

App用戶端架構演化之路

各層的分工如下:

  • View層:顯示層,負責UI的渲染。
  • Controller層:作為View層和ViewModel層中間層對上提供資料給View層展示,對下負響應使用者的互動。
  • ViewModel層:負責掌新APP業務邏輯封裝,如預約課程等業務邏輯,對上層提供業務封裝後的接口。
  • Service層:負責具體的業務實作,包括對網絡請求的封裝以及請求後傳回的資料的包裝、整理、解析等,緩存等。
  • Modle層:資料層。
  • mPass層:主要負責提供一些底層的功能支援,如資料庫、拍照、分享等。

對比2.0架構,我們是在ViewModel層和Model層之間插入了一個Service層,對于此次架構調整優點如下:

  1. Controller層隻用來做中轉層不參與業務邏輯等處理
  2. Controller層對上(View層)隻提供頁面展示所需資料,對下調用(ViewModel層)暴露出的業務邏輯接口
  3. 友善進行功能,業務邏輯的單元測試
  4. ViewModel層實作整個業務邏輯,實作對上層隻提供接口是以此層靈活,易維護
  5. Service負責具體業務的實作,并對資料進行封裝、整理等

對比1.0架構,我們是在原有的Controller層和Service層之間插入了一個ViewModel層,架構調整前後對比如下表:

App架構1.0 App架構2.0+
Controller控制層過于臃腫複雜 Controller層隻用來做中轉層不參與業務邏輯等處理
老的Controller層包含了業務邏輯代碼使此層的代碼量超大并且臃腫不易維護 Controller層對上(View層)隻提供頁面展示所需資料,對下調用(ViewModel層)暴露出的業務邏輯接口
Controller層包含業務邏輯不能較好,靈活的擴充,分隔等 ViewModel層實作整個業務邏輯,實作對上層隻提供接口是以此層靈活,易維護,具體的資料的包裝等業務邏輯交個Service層
不能進行功能,業務邏輯的單元測試 友善進行功能,業務邏輯的單元測試

4、App架構3.0

都是基于目前我參與的樂聽說基于2.0+架構采用swift開發的口語評測App,留留學、新東方、樂聽說App等現有架構可實作内部豎向解耦,後續開發中我們将逐漸實作各個層同層内部子子產品的解耦工作(橫向解耦);同層之間各個子子產品之間調用互相依賴,會嚴重影響各個子產品之間的解耦,如A子產品内部(甚至外部)依賴B、C子產品,而B、C子產品又依賴A子產品,這種互相依賴、互相include的情況導緻各個子產品互相不能獨立,嚴重影響編譯速度和擴充性、靈活性等, 在後續版本中為了完成橫向解耦我們内部将開發實作一個動态路由元件(DR,Dynamic Route),以樂聽說為例進行說明,如下圖:

App用戶端架構演化之路

路由實作方案簡圖如下:

App用戶端架構演化之路

5、子產品化結合Pods

參與的項目基本都是采用子產品化開發,盡量實作高内聚低耦合,以掌上新東方為例,App研發子產品以及對接平台衆多,我們采用MVVM架構(後期采用MVVM+架構)進行子產品化開發,實作工程的可擴充性以及易維護性,盡量做到高内聚低耦合。如下圖:

App用戶端架構演化之路

當公司裡面有多個項目同時進行,并且有可能是多個人分别不同項目時,就會存在相同子產品重複開發,其實每個APP中都是有很多共同的子產品,當然有可能你會把相同功能子產品代碼複制一份在新項目中,但這其實并不是最好的方式,在後期不斷疊代過程中,不同的人會往裡面增加很多帶有個人色彩的代碼;這樣就像相同的子產品項目後期對于多個項目統一管理也是災難性,有可能會失控,哪怕項目轉移别人接手也會無形中浪費很多時間,增加維護成本,是以執行個體中更注重對于一些相同子產品進行提取,求同存異。

我們将嘗試采用子產品化結合Pods進行管理,對于常用功能的封裝,隻要開放出一些簡單開關配置方式,就可以實作一個功能,比如日志記錄、網絡請求子產品、網絡狀态變化提示等。

将分OC和Swift語言開發兩套對應的路由元件,會優先着手OC版本的研發,由于之前都忙于項目開發,近期會抽時間對代碼進行完善(LLRouter),如有好的思路和見解,可以給我提issues,核心代碼如下圖:

App用戶端架構演化之路

6、總結

App架構以及相關性能的優化不是一蹴而就的,需要不斷的探索和鑽研!同時架構沒有真正的好壞之分,隻要适用于自己的業務,就是好的架構!

以上隻是我的一些心得和感悟,肯定有一些地方需要完善,如有不對或不恰當,望大家留言讨論!