安卓專案架構設計-梳理現有專案的混亂

語言: CN / TW / HK

架構設計通常發生在一個專案生長到一定程度時,結束了野蠻生長進入穩定期,回過頭來審視整體專案的架構,大多是一個比較混亂的狀態。本文將從現有專案出發,梳理專案中混亂的結構,講述專案架構設計的過程。

一、目標與規劃

1.1 完整的專案架構

對於一個成熟專案來說,專案架構中應該包含基礎層、核心層、業務層、應用層、跨平臺層共計5個層次。

  1. 基礎層包含一些最基本的能力。原則上應該是可以脫離公司特定的環境、不依賴其他非基礎層模組、功能單一且健壯,比如異常檢測、行為埋點、網路請求、圖片載入、非同步處理、全域性UI等等,基礎層大多可以引用三方庫。
  2. 核心層包含一些可以在公司環境下跨APP使用的能力。原則上應該是業務層的主要支撐、不依賴其他非基礎層和核心層模組、功能單一且健壯,比如MVP或MVVM框架、應用配置、版本控制、日誌、監控、熱修復、三方平臺開放能力對接等等,核心層通常是自研或基於三方庫包裝或改造。
  3. 業務層包含一些比較獨立、邊界比較清楚的業務。在這一層開始會有Activity,就會涉及到模組間頁面跳轉的問題,通常由一個獨立的路由模組負責。業務模組原則上應該專注於單一的業務功能,比如使用者登入、個人主頁等等。
  4. 應用層則是APP主體專案,多個APP可以在應用層引用不同的業務模組,搭建自身的應用能力。
  5. 跨平臺層應該根據團隊的技術偏好進行選擇,需要與否、技術方向都可以酌情考量。

1.2 專案演進規劃

  1. 梳理現有專案 的整體架構是重中之重,每次重構我們都必須確保業務邏輯不應被影響,各個自研模組、依賴的三方庫都應納入考量。從專案中剝離出哪些功能進入基礎層、核心層、業務層,現有模組中有哪些需要拆分、改造、刪除,都需要在梳理完成後就列出來,保證後續的規劃可以順利推進。
  2. 重構的節奏 很重要,業務不可能停滯下來等待重構結果,業務與重構雙線進行在最後合併時會有大量的衝突,重構的結果沒有業務進行驗證也增長了上線的風險。最好是小步快跑的模式,現在大多團隊都是敏捷開發的業務模式,重構按小模組小功能進行,一點點和業務融合,在測試和上線時都可以控制風險。
  3. 三方庫 可以減少很多開發的工作量,但在選擇三方庫時要注意幾個原則:
    1. 維護團隊和社群比較大,遇到問題後能夠有足夠多的自助解決空間;
    2. 底層功能強大,支撐儘可能多的上層應用場景;
    3. 拓展能力靈活,支援在框架基礎上做能力拓展和AOP處理;
    4. Api側友好,降低上層的理解和使用成本。
  4. 基礎層 應該是最先搭建起來的,從梳理結果中將基礎模組陸續剝離出來,由於核心層和業務層都強依賴基礎層,所以一個完善的基礎層可以加快核心層和業務層搭建的速度。重構的過程中,每次抽離基礎層應該會修改大量上層程式碼,在上層模組比較少甚至只有一個的時候,改動會方便很多。
  5. 核心層 在基礎層完成後進行搭建,主要目的就是讓業務層更好更快的完成一個業務的開發,將業務無關的、可在多個業務複用的功能封裝成模組。核心層抽離時對上層的改動會小一些,但由於緊靠業務層,改動時必須很謹慎,容易對業務邏輯造成影響。
  6. 業務層 是所謂模組化的表現,主要目的是方便團隊協同開發,在大型複雜專案中跨業務組做需求可以減少衝突。如果團隊規模較小,業務耦合比較高,也可以考慮不拆分。
  7. 跨平臺層 和業務層不同,它本身就是比較獨立的部分,拆分也簡單,不拆分影響也不大。

二、制定重構計劃

2.1 專案梳理

  1. 如果專案已經是有多個模組,那麼第一步就是梳理所有模組的能力,明確每個模組記憶體在的資原始檔、UI元件。梳理完模組,再梳理應用的所有功能、UI元件、資原始檔。這一步是最耗費時間的,一定要仔細挖掘所有程式碼,否則在拆分模組的時候就是大坑,到時再來修改方案就比較費時費力了。
  2. 把梳理出的所有功能、UI元件、資原始檔,按各個業務進行歸類,不能歸屬到具體業務的算做應用層,先把各個業務理清楚,暫時不管是否可以拆成核心模組和基礎模組。
  3. 業務梳理完會得到一個應用層和業務層的專案結構,這時候開始從應用層到業務層重新梳理,篩選出可以拆成核心模組的部分。這時候要注意是否存在相似甚至完全一致的功能,可以考慮合併成一個功能或者是一系列功能。
  4. 現在我們有了應用層、業務層和核心層,已經比較複雜了,注意要耐心仔細。再重新從應用層->業務層->核心層進行梳理,獨立出基礎模組。注意UI元件、全域性樣式比較容易被忽略,有一個統一的UI模組會方便上層搭建UI介面,減少資源冗餘。

2.2 拆分模組安排

梳理完成後,我們有了一個現有專案可拆分模組的梳理表,整體架構從應用層->業務層->核心層->基礎層該拆成什麼樣應該已經很明確了。

現在可以安排拆分的模組,這時應該自底向上開始拆分,把基礎模組一個個搭建出來,小步快跑的模式。剛開始拆分出基礎模組時,上層的改動會比較大,動輒數百個改動都是常見的,一定要謹小慎微。我們把原本只包含一個應用層的專案,向下抽取了一個包含網路庫、圖片載入庫和UI庫等眾多原子能力庫的基礎層。這樣做之後,對於協同開發、整包構建和程式碼複用都起到了很大的改善作用。

基礎層搭建完成後,可以開始拆分核心層。從全域性視角來看,基礎層和核心層也能作為一個整體,共同支撐上層業務。這裡將其分為兩層,主要考慮到前者是必選項,是整體架構的必要組成部分;後者是可選項,但同時也是衡量一個App中臺能力的核心指標。

有了核心層就可以對業務層進行拆分了,通常一個迭代會有多個需求,一個需求通常是在一個獨立的業務中的,通常很難保證迭代裡的所有需求都能按時交付,如果沒有獨立的業務模組,要麼整體延期要麼就得進行痛苦的分離工作。如果有業務層,那麼只需要不將延期的業務模組更新到應用層,整體迭代發版還是可以順利進行的。

如果為了在一些業務需求上減少開發工作量,讓一份程式碼同時在安卓和IOS上執行,單人開發也降低了需求溝通的成本,引入了跨平臺的能力,那麼就可以從應用層再抽離出一個跨平臺層。

至此,一個相對完整的端側系統架構已經初具雛形了。後續業務上會繼續有著更多的迭代,但專案的整體結構基本都不會偏離太多,更多的是針對於當前架構中的某些節點做更深層次的改進和完善。