1. 程式人生 > IOS開發 >App架構二三事

App架構二三事

一、概述

1、架構 & 架構師

  • 架構一詞源於建築學,原指建築物在其尺度上,依靠內部支撐物相互結合,而穩固構造的方式。
  • 在軟體行業中,架構可分為:業務架構應用架構技術架構;其中,業務架構是最頂層的設計,技術架構是基建,而應用架構承上啟下:上承接業務架構的落地,下決定技術的選型。
  • 我們接觸最多的是應用架構,主要職責:拆分(邊界劃分)系統/模組/元件,定義各組成成分之間的分工和合作;平衡業務、技術和團隊的複雜度;最終目的是保障業務順利落地。
  • 架構師們需要先了解業務架構;然後根據業務架構,設計相應的應用架構,最終推動應用架構落地,升級和完善技術架構;因此,架構師的職責可以歸納為:**理解業務、全域性把控;技術選型,解決關鍵問題、指導技術落地實施 **。

2、衡量架構的合理性

  • 架構是為業務服務的,沒有最優的架構,只有最合適的架構;一般從業務需求角度非業務需求角度來評估架構的合理性。
  • 業務需求角度
    • 能解決當下業務需求和問題
    • 能優雅且可複用地解決當下絕大部分業務問題
    • 能適應未來一段時間內的業務迭代,而不會因業務大量迭代要大改甚至推翻原來架構。
  • 非業務需求角度
    • 穩定:服務穩定,如App的Crash率萬分之五,OOM率萬分之一,後端服務可用99.99%
    • 安全:資料和程式碼安全等
    • 高效:功能可擴充套件、功能高複用

3、前後端架構

  • 移動網際網路時代,前後端分離的背景下:大前端(前端、移動端)關注互動體驗,後端關注高並低延,這些都導致前後端的架構方案走向完全不同的道路。
  • 後端應用架構發生了從單體應用->分散式應用->微服務的演進;微服務架構通過更細粒度的服務和設計準則來實現大規模、複雜的後端應用架構設計。
  • 大前端應用架構發生了從單工程->元件化的演進,元件化架構採用獨立元件的方式,實現了工程和程式碼的解耦,適合複雜業務中,多團隊之間的分工和合作。
  • 雖然微服務元件化是兩個完全不同的領域,但是核心目標卻一致:分離業務(元件/模組/系統)的邊界和責任,保證各組成成分的獨立部署、維護和升級,最終由聚合在一起,服務於使用者。
  • 前端專案在元件化之後,也慢慢吸收微服務思想,演化出微前端架構,業內有一些嘗試,如:前端微服務在位元組跳動的落地之路

二、App架構-元件化

1、概述

  • App架構指的是App的應用架構,是服務於業務架構的一部分;在App的應用架構中,主要關注以下兩點:
    • 職責劃分:邏輯分層,元件劃分,明確各層級、各元件之間的邊界和責任
    • 職責協作:定義層,元件對外提供的能力,規範層與層之間,元件和元件之間的協作(呼叫)關係;
  • App架構中的分層是橫向劃分,可以將App應用劃分成N層,具體的元件分割在不同層中,每一層保持內聚性,並且與它下面的各層保持鬆散耦合。
  • App架構除了定義好職責劃分和協作,還需要以下一些內容:
    • 開發技術選型:開發語言,框架和工具
    • 架構模式:MVC、MVVM
    • 開發/編碼規範

2、現狀

  • App一般分iOS和Android兩端,除了平臺特有的一些特性,大體架構其實是差不多的;分層、元件化、開發架構模式等都是可相互借鑑的。
  • Android在元件化基礎上,利用外掛化實現功能的動態下載和更新;但是由於蘋果對動態化的限制,iOS外掛化實踐非常少。
  • 大型的App專案,元件化落地後,程式碼、業務職責更加清晰了,不同的元件由不同團隊or個人維護、升級;然後職責的分散依然需要服從統一的規範和管理,否則程式碼質量、開發效率等難以避免發生劣化;
  • 很多小App專案,建議有選擇地實踐元件化,盲目推動元件化,可能會給開發人員帶來負擔,降低開發效率,拖累業務發展。

3、元件化簡介

  • 三層架構 + 元件拆分 ;從上到下層級可以是:業務層容器層基礎層;將專案拆分成不同元件(一個元件可以是一個單獨的工程,隔離程式碼和資源,可以獨立編譯和執行),每個元件在不同的層級。層級可以是:

    • 業務層:各類業務元件,如使用者登入、分享、直播等業務元件。
    • 容器層:架構的核心,為應用提供App生命週期管理、事件分發,負責元件間的排程和訊息派發。
    • 基礎層:主要是基礎元件,包含基礎庫,如網路功能、圖片載入,效能監控,資料儲存,日誌系統等。微信支付寶SDK;

    選擇合適的粒度拆分元件;業務變更很快 or 不會被重用的業務模組,可以粗放式劃分,不必投入過多精力,優先保障業務進度;

  • 容器層

    • App生命週期、事件分發等管理:
      • 實現一對多的訊息分發,類似於iOS的通知中心 or Android的釋出/訂閱機制(EventBus)
    • 元件間通訊
      • URL路由:通過URL喚起服務;iOS可參考MJRouter、、Android可參考Arouter
      • 中介者:通過中介者實現元件之間通訊,元件和元件之間無依賴,無耦合;iOS有CTMeditor
      • Procotol Class繫結:定義元件提供服務的協議,具體由元件實現;元件和元件之間有依賴,但是耦合低;IOS有BeeHive
  • 元件整合:殼工程中保留工程配置選項依賴庫管理檔案;利用元件管理工具將元件整合在一起,iOS可以CocoaPods、Android可以用Gradle;

4、元件化後變化

  • 多元件工程開發:每一個元件對應一個工程,每個需求會修改多個元件工程的程式碼和資原始檔;
  • 多業務團隊協作:不同元件交由不同團隊 or 個人負責,App每個版本都涉及多個團隊之間協作;比如某個版本需求,直播間新增一個登入後可以發紅包功能,這裡面會涉及到支付團隊,直播團隊還有UG團隊之間的協作。
  • 並行開發:App每一個版本對應不同元件工程修改,這些個元件工程合併在一起稱為基線;每次封版之後,參與下一個版本迭代的同學都需要基於穩定的基線做開發。

5、完善基建的訴求

  • 建設 多工程程式碼管理工具,支援多工程clone、commit、push和merge等基本操作
  • 建設 多工程MR管理平臺,支援不同元件工程程式碼lint、工程合碼、發版和整合;
  • 建設 元件庫管理平臺,支援管理各元件的的原始碼&二進位制、依賴、升級和發版等;

​ 元件化後,基礎建設未完善之前,明顯到開發效率降低;甚至懷念當年單工程時代;從另一方面也說明,基礎建設能力完善,也能很好推動架構的演進;

三、App架構-架構模式

架構模式:指導設計程式的結構,目前常見的架構模式有:MVCMVPMVVM

1、Apple MVC 介紹

  • MVC(Model–View–Controller)分為三個基礎部分:模型(Model):模型層,資料及其處理;檢視(View): 檢視層,UI展示和互動;控制器(Controller):響應使用者輸入,並通知模型、檢視更新。MVC有經典MVCApple MVC,Apple MVC和經典MVC最大的不同是,Apple MVC隔離View和Model的通訊

Apple-MVC

  • Apple MVC中,Controller持有View和Model,當Model發生變化時候,可以利用通知、代理或KVO(iOS特有)等方式通知Controller;Controller可以直接根據Model來決定View的展示。View接收到響應事件,通過delegatetarget-action等方式告訴Controller的狀態變化。

  • Apple MVC中,一個典型UI互動的過程:

    • View接受使用者操作傳送給Controller;
    • Controller根據操作對Model進行修改;
    • Controller接受Model修改的通知,並根據通知更新對應的UI;
  • Controller層膨脹(Model-View-Controller -> Massive-View-Controller)的原因有二:

    • Controller持有View和Model,幾乎可以控制所有邏輯,隨著Controller和Model、View的通訊越來越多,Controller中程式碼也越來越多;
    • 一般情況下,Android的Activity,iOS的ViewController 即當View層又當Controller層,並沒有將View層 和 Controller層進行分離;這些都加劇了Activity/ViewController的臃腫。
  • 此外,厚重的Controller很難測試,不管是手動測試或是使用單元測試,因為有太多可能的狀態。為解決Controller臃腫問題,衍生出MVC的變種:MVP和MVVM.

2、MVP 介紹

  • MVP(Modell-View-Presenter)主要有三部分Model、View和Presenter,其中View持有Presenter,Presenter持有Model,和Apple MVC一樣,View和Model是不通訊的,具體的控制邏輯在Presenter,Activity/ViewController主要作用是響應生命週期和顯示UI。

    MVP

  • MVP模式解決了Controller的臃腫問題,使得軟體結構更加清晰,真正意義上的將UI邏輯和資料邏輯隔離了,Presenter層和Model層都可以做單元測試;

  • 但是MVP模式下,Presenter層不僅有控制邏輯,還有大量View->Model,Model->View的同步邏輯,造成Presenter比較臃腫。

3、MVVM介紹

  • MVVM(Model-View-ViewModel)主要有三部分:Model、View和ViewModel,其中View持有ViewModel,ViewModel持有Model;View和Model是不通訊的,具體邏輯在ViewModel;

MVVM

  • MVVM使用一種雙向繫結機制,使得 Model 變化時,ViewModel 會自動更新;而 ViewModel 變化時,View 也會自動變化;

  • 在實現雙向資料繫結方案上,iOS可以使用 KVO 或 Notification or ReactiveCocoa框架;Android可以使用Google提供的DataBinding;

  • MVVM模式降低了View和Model之間的耦合;分離了業務邏輯和檢視邏輯;可解決MVC模式中Controller過於臃腫,MVP中Presenter過於臃腫;

  • 但是MVVM模式下:View和Model雙向繫結導致bug難以定位,兩者中的任何一方出現問題,另一方也會出現問題;

​ ReactiveCocoa是個很好的框架,很多iOS團隊使用ReactiveCocoa框架來實現資料的雙向繫結 ;但是鑑於ReactiveCocoa學習和維護成本比較高、只是做雙向繫結有點大材小用,我們是個用了更輕量級的KVOController

四、iOS元件間通訊方案

iOS元件之間通訊一般採用三種方案:URL路由、Protocol Class繫結、中介者;

1、URL路由

  • 簡介

    • 根據URL註冊對應的服務,然後通過URL呼叫;
    • iOS經典實現:蘑菇街的MGJRouter;提前註冊好URL 和 服務Block & 引數字典的對應關係(儲存在router字典中),然後利用URL找到對應的Block,將引數字典交給Block,喚起對應的服務。
  • 特點

    • 使用簡單,非常適合統一Android和iOS雙端頁面跳轉,對專案運營幫助很大;
    • URL路由不適用調起埋點、日誌上報、Network請求處理、圖片載入,資料儲存等等基礎元件服務;
    • 註冊分散、引數字典不方便傳遞比較複雜的引數,如UIImage、自定義Model等;還需要專門維護URL;

2、Protocol Class繫結

  • 簡介

    • 面向協議程式設計,定義好服務協議,具體由元件實現;元件依賴的是協議,而非具體實現;
    • iOS經典實現:阿里的BeeHive;提前註冊Protocol+Class的對應關係,然後根據Protocol獲得對應的實現Class,獲取對應的服務;降低了模組之間的耦合;具體可見BeeHive —— 一個優雅但還在完善中的解耦框架
  • 特點

    • 通用性比較強,協議和實現分離,直接依賴協議即可;
    • 缺少統一排程層,難於集中管理;無法避免對協議類的依賴;

3、中介者

  • 簡介

    • 使用中介者統一排程元件間通訊;
    • iOS經典實現:Casa的CTMediator;業務上定義好服務方法,方法內部通過performTarget方法呼叫服務方元件的Target、Action,利用Runtime實現解耦;
  • 特點

    • 中介者能實現統一管理元件服務;
    • CTMediator實現上,需要明確Target、Action符號名,需要很多硬編碼;編譯階段不檢查,執行時才檢查對應類或者方法是否存在。

4、總結

  • URL路由Protocol Class繫結都需要在註冊後,才能提供服務;
  • URL註冊本質是使用字串常量代替原有的函式宣告,這樣就不用引用頭⽂件,但是因為沒有函式和引數宣告,影響業務使用效率;而Protocol Class繫結提供了函式和引數宣告,方便業務理解和使用,但是元件使用時,需要依賴協議;
  • 在對元件服務管理上,中介者比URL路由Protocol Class繫結有更強的控制和管理能力;
  • 三種通訊方案都是為瞭解耦元件;而解耦並不僅僅為了實現編譯上解耦(如,元件間檔案無引用),更多是為了:分離業務邏輯和職責;因此,在業務中,根據實際情況選擇方案;架構方面,更多的精力是在:保證上下層依賴清晰、元件間呼叫清晰。

歷史文章

漫談技術演進和思考

參考文章

什麼是真正的架構

開篇 | 模組化與解耦式開發在螞蟻金服 mPaaS 深度實踐探討

支付寶客戶端架構解析:Android 容器化框架初探

Android元件化方案及元件訊息匯流排modular-event實戰

美團外賣iOS多端複用的推動、支撐與思考

元件和模組的區別

元件化架構漫談

解讀 iOS 元件化與路由的本質

MVC、MVP、MVVM的演化

Model-View-ViewModel for iOS

iOS 元件通訊方案