什麼纔是真正的架構設計?

就算你是一個打螺絲的,你依然每天遊走在這個系統的 “架構” 裏,在裏面修修補補,你得從 “架構” 的全局角度去審視你每天忙碌的價值和意義。經歷的項目多了, 在進入新的團隊,有些老項目,在瞭解業務背景後, 你頭腦中可能已經閃現出一張 “架構” 了,然後你去看代碼的時候大喜:“果然如此”, 這種 “架構” 背後的代碼讓你讀起來神清氣爽;也有些項目,你在讀代碼的時候發現和你腦海中閃現的 “架構” 不一樣,這時你只能罵咧咧的合上筆記本,心想怎麼會 “架構” 出來這種坨坨,喝杯咖啡之後,繼續來啃裏面的“屎山”。

01 什麼是架構

前面多處提到了 “架構” 這個詞,架構架構,到底什麼是架構?,每個人都有不同的理解,實際工作中,對於同一張架構設計圖,由於不同的人對於 “架構”、“系統”、“模塊” 這些相關概念的理解不一,討論的時候往往很難形成統一結論。

首先搞清楚什麼是 “架構”, 網絡上有不少文章對此做解釋, 其中李運華大佬的《從零開始學架構》前兩個章節介紹得比較清晰。“架構” 一詞可以作爲名詞, 也可以作爲動詞。作爲名詞描述的是軟件的結構組織關係;作爲動詞,指軟件結構的設計和演變過程。先來看看做爲名稱, 架構的組成要素:

系統: 當 “架構” 做名詞的時候, 可以簡單的把系統同等預架構, 可以說一個 App 的系統架構。

模塊: 系統不能描述架構的內部細節, 需要劃分爲各個模塊, 例如 xxApp 的架構:

組件: 可以認爲是系統的最小組成單元,例如消息模塊, 如果繼續細化的話, 可以拆分成消息發送器、消息接收器等組件。

關聯: 組件、模塊往往不是獨立存在的,通常都存在着某種關聯, 例如消息模塊和用戶模塊,存在着依賴關係。

子系統: 當一個架構規模和複雜度都比較大時,光用模塊和組件可能已經描述不清楚了, 可以進一步把某些相關的模塊羣化爲子系統。例如微信可能的架構圖:

以上從架構的名詞層面對齊了架構組成元素的概念。“架構” 作爲動詞的時候,我們討論的是架構的一些方法論。

02 縱向架構

縱向架構,強調的是分層,核心就是分層思想,這個在操作系統架構上已經是一個經久不衰的設計思想了。

這樣分層隔離的好處不言而喻, 如果你做過 Android 模擬器開發, 你就知道這裏的 HAL 層是多麼重要, 通過它可以輕易替換 Linux kernel 的實現, 通過模擬,讓 Android 可以輕鬆跑在 Windows 的系統裏。

分層架構是一種將系統程序按功能和職責劃分爲不同層次的設計方法。每一層都有其特定的職責, 通過清晰的接口與其他層進行交互。這種架構方式有助於提高代碼的組織性、可維護性和可測試性, 可以輕鬆的替換、擴展其中一層的核心能力。關於 App 如何做分層架構設計, 我在 16 年就寫過一篇文章《Android 應用架構概述 https://www.jianshu.com/p/e157cc64ea5c》 , 現在回頭看, 分層的本質思想依然沒有變。

03 三層架構

最基本的分層架構通常包含以下三層:

04 四層架構

一定規模的 App 通常還會繼續分層,例如可以擴展出基礎層出來。

表達的是分層的思想和方法, 具體分多少層, 取決於 App 規模和複雜度。

檢驗標準: 是否成功做到了分層, 檢驗的標準就是是否真正給 App 帶來了前面提到的分層的好處,例如:要替換其中一層裏的核心能力,是否可以低成本就替換, 當某一層修改的時候, 是否可以單獨的對該層進行單元測試。

05 橫向架構

隨着 App 功能規模、團隊規模不斷擴大, 這時候可能需要層業務模塊角度關注架構設計,目的是降低功能規模增加而帶來的複雜度爆炸增長,橫向架構強調的是業務模塊之間的橫向解耦,從而降低複雜度。

   5.1 複雜度的評估

圖中 4 個模塊都存在着依賴關係, 那麼複雜度計算爲 24:複雜度 = 4x3x2x1

如果我們通過某種手段進行解耦(例如通過增加一個 api 服務層隔離):

通過這樣解耦,複雜度變爲了 5:四個模塊加一個隔離層。

通過上面的分析,基本可以看到, 模塊化解耦是一個 App 發展到一定規模後繞不開的話題, 淘寶、微信等這樣的巨型 App 早已在迭代過程中進行了多輪的模塊化重構, 參考:《微信 Android 模塊化架構重構實踐

https://cloud.tencent.com/developer/article/1005631》

檢驗標準: 橫向架構是否成功, 檢驗的標準是,如果這個模塊給獨立小組開發,是否可以獨立開發、編譯、調試。

   5.2 架構不是一套打遍天下

我經歷過幾十萬、幾百萬的中小型 App 搭建, 也參與千萬日活的大型 App 應用架構,後者的架構更復雜,用到的技術和手段也更豐富,是不是就可以把後者套用上去呢?答案顯然是否定的,不可能說微信的架構很牛, 那我們就搬過來用。架構設計需要滿足三原則:

詳細可以參考:

《架構設計三原則 https://time.geekbang.org/column/article/7071》

   5.3 先有架構再有設計模式

初入這個行業的時候, 很多設計模式是看得雲裏霧裏, 我覺得是我們搞反了順序,導致我們很難理解爲什麼用這個模式、 SOLID 設計原則有什麼作用。

應該是先有業務場景, 然後再有什麼樣的架構, 爲了到達這個架構的要求, 然後纔是各種設計模式和設計原則的靈活選取和應用。

例如,我們爲了讓用戶模塊和消息模塊解耦,假設用戶模塊依賴消息模塊的未讀消息數這個信息。

爲了滿足橫向架構的要求,解除模塊依賴,架構變成:

通過這樣調整,我們不知不覺中使用了 SOLID 中的好幾個原則,例如依賴倒置原則。

   5.4 跨平臺和動態性

跨平臺和動態性是做 App 架構繞不開的一個話題。

兩類跨平臺: 第一:UI 跨平臺,代表方案 WebView、Weex、RN、Flutter 等類 web 方案。

第二:C++ 跨平臺, 通常是在追求性能的某些特定場景, 例如音視頻編解碼處理,某些複雜的加解密算法等。也有一些團隊由於領導班子技術棧的優勢, 會選擇將業務甚至 UI 也是用 C++ 跨平臺,例如騰訊會議。

動態性: 代表方案 WebView,Weex ,小程序等類 web 方案和原生插件化方案。

關於怎麼選取,我們要完美的動態性或者跨平臺性的時候,可能就是犧牲了某些性能,例如 WebView ,在跨平臺性和動態性都堪稱完美,但卻是可選方案中性能最差的,再比如:如果我們使用 C++ ,性能上肯定沒問題,但是在開發效率、團隊人員技術要求上都要面臨巨大挑戰。

還有些選擇是由業務本身決定的,例如類似應用寶這樣的應用商店應用,根本就不用考慮跨平臺問題, 因爲它只能跑在 Android 平臺, 但是它對動態性要求非常高,作爲廠商的競爭對象無法在廠商應用商店上架,所以類似插件化這樣的動態方案就顯得非常重要。

架構中對於動態性和跨平臺方案的選取,這同樣是一個取捨問題, 架構乾的活,大多數時候都是在做取捨和平衡。

06 總結

  1. 架構作爲名稱描述 App 系統組織元素和組織關係。

  2. 架構作爲動詞,強調的是架構的整體方法論, 縱向分層架構,橫向模塊化隔離架構,在此之下靈活使用設計模式和設計原則實現架構目標。

  3. 架構要適應業務自身需求和變化, 做到三原則。

原創作者|劉光利

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/7_SU77SKgI-GLyjMZeavsQ