軟體架構:分層架構模式 ( Layered Architecture )

YC
程式愛好者
Published in
Jul 19, 2021

作為最常見的架構模式,分層架構模式被不同語言與框架大量使用,因此被大多數架構師、開發人員所熟知。

什麼是分層架構?

一個分層軟體架構,可以大概被簡化成以上的層次。

有些同學一看就會發現,這不就是擴展版 MVC 嗎? 對的,也可以說 MVC 這個架構概念就是一個很常見的分層架構!

我相信各位在入門剛開始進入軟體開發都有聽過、用過 MVC 這種開發模式,而這種開發模式可以說是出現在各大層面上,今天的 iOS 、Android 、Backend (Web 除外) 的框架都有大量使用到 MVC 這種簡化的分層架構。在這次我們無法用太多篇幅來跟大家討論 MVC,之後我會開一章來詳細討論 MVC 的細節。

而上圖的分層架構模式可以說是更抽象,也更有效的對程式進行分類。

分層架構模式中的每一層都有特定的角色和職責,如下:
表示層 (Presentation Layer) 負責處理所有用戶界面 (User Interface) 和瀏覽器通信邏輯。
業務層 (Business Layer) 將負責處理軟體本身特定的業務邏輯 (Business Logic)。
持久層 (Persistence Layer) 則專注於資料的儲取活動。
最後資料訪問層 (Data Access Layer) 泛指外部資料來源 (通常獨立於應用程式)。

我個人會選擇把 Controller 放到 Presentation Layer 當中,因為 Controller 本身不應該擁有 Business Logic。另外,業務層和持久層也可以合併為單個業務層,因此較小的應用程序可能只有三層,而較大和更複雜的業務應用程序可能包含五層或 N 層。

分層模式中的一個重點在於對不同角色進行隔離,而隔離的目標是︰當一層中進行更改時,通常不應該影響到非相關依賴層。當你允許表示層直接訪問持久層,而持久層內對 SQL 所做的更改將影響業務層和表示層,惺當下一次要改動表示層時,卻有可能反過來影響到持久層或業務層,使得程式的耦合性非常高,亦非常難以修改。

在分層模式中任一層都應該對其他層的內部工作知之甚少或一無所知。假如層與層之間的契約/介面 (Contract/Interface) 保持不變,任一層的更動都不應該影響到其他層。

為什麼要用分層架構 ?

這種廣為人知的架構模式,有幾點好處可以注意的:

  1. 易於理解與開發
    分層模式相信是很容易被解理,因為程式邏輯很線性,資料流主要就是從上到下或是從下往上,實行起來並不復雜。大多數公司亦通過按層來提出UI 需求、業務需求等來開發應用程序,所以分層模式自然成為大多數業務應用程序開發的直覺。
  2. 關注點分離(Separation of concerns, SoC)
    每一層中的組件只處理與該層相關的邏輯。例如,表示層中的組件只處理表示邏輯、業務層中的組件只處理業務邏輯。這種程式分類方法可以有效地將軟體中不同的角色進行分割,而定義明確的組件接口和有限的組件範圍,可以讓開發、測試與維護 (可能 ) 變得更簡單。
  3. 可測試性
    由於分層明確,在單元測試中其他層更容易被模擬,使得分層模式相對容易測試。開發人員可以選擇模擬表示層以對業務組件單獨進行測試,也可以模擬數據層以對持久組件進行測試。

什麼時候不要用分層架構 ?

  1. 沉洞反模式 ( Sinkhole Anti-Pattern )
    如果請求會流過架構的多個層,但每一層內都只執行很少甚至沒有邏輯時,我們應該把多層合併,或開放不同層之間的隔離狀態。例如,當表示層接到請求後將請求傳遞給業務層,業務層直接地將請求轉傳到持久層,然後持久層對數據庫層進行簡單的 CRUD,最後 data 再一直向上傳遞並送出回應。
    我們不應該增加不同的層來提高資料流與軟體架構的複雜度相反,更適合以簡單的層次劃分來設計軟體。
  2. 可擴展性不足
    分層模式更傾向於成為一個單體應用,因此軟體擴展性不足。當軟體發展得愈來愈大,最於整個分層架構仍然會變成一個巨無霸軟體,對程式碼維護與耦合性仍有一定程度的影響。

分層架構常常被使用在單體應用 (Monolithic Applications) 當中,但其實我們仍可以在不同的架構模式中使用分層架構模式。如在微服務架構當中,我們仍然可以選擇使用分層架構作為某個服務的軟體架構,可見分層架構可以與其他架構模式做結合。

如果你覺得我的文章幫助到你,希望你也可以為文章拍手,分別 Follow 我的個人頁與程式愛好者,按讚我們的粉絲頁喔,支持我們推出更多更好的內容創作!

--

--

YC
程式愛好者

提供更精確的技術內容為目標,另創立「程式愛好者」專頁。資深軟體工程師,專研後端技術、物件導向、軟體架構。