軟體分層設計模式是我這幾年專案必會使用的架構,它的效益在多人團隊分工上有極大的效益,且能有效專注修改區域,提高共用性。
三層式架構 (Three-Tier) 是很常見的架構,可以應用在實體機器架構上,也可以應用在邏輯架構上,可以按照實體與邏輯上去進行區分。
為甚麼要分層?
如果程式全部一條龍寫到底,後續會產生很多問題,難以維護、難以閱讀、更甚至是萬一人家要接手你的程式碼,這時候改A壞B,耦合度過高的情況下,你只能祈禱接手的人不知道你住哪…
這種情況下只有自己寫可能還好,那如果需要跟人合作呢?
大家可能容易出現重複的 Code,也難以說明誰該負責寫哪部分。
這時候有一個好的架構,就很重要了,分層設計時,遵循了面向介面設計的思想,那麼這種向下的依賴也應該是一種弱依賴關係。因而在不改變介面定義的前提下,理想的分層式架構,應該是一個支持可抽取、可替換的「抽屜」式架構。
WebAPI 的三層式架構
WebAPI 的三層式架構顧名思義,主要分為了三層:
- Controller: 控制層,作為接口。
- Service: 商業邏輯層,只要有關商業邏輯部分的處理全部放在這一層。
- Repository: 倉儲層,作為資料存儲的一層。
- Common: 共用層,作為存放各層會用到的相同東西。
他們之間的關係如下圖:
優缺點
優點 |
---|
1、較好形成一個規範,可做為標準化流程。 |
2、提高重用性,透過分層將相同類型的程式碼放在一塊。 |
3、團體合作的時候,能夠分層進行;開發人員只需專注於自己開發的那一層即可。 |
4、具有好的開放性、可擴充性優點。 |
5、降低程式碼之間的依賴,每層溝通是透過介面。 |
6、提高系統安全性,因為使用者需要透過 Service 層才有機會與下一層 Repository 撈取資料。 |
缺點 |
---|
1、增加了開發成本,傳統一個人負責寫到底;分層下需要多人進行合作。 |
2、調整程式可能會出現連動性;有的時候修改一個地方,會導致其他層也需要跟著調整。 |
3、相較於一條龍開發系統性能下降,原本程式可以直接透過 DB 撈取資料,現在需要透過中間層的轉介才能夠拿到。 |
Controller
在我們 WebAPI 中,Controller 就屬於『接口』,負責處理 Router,如常見的:Get、Post、Patch…等,都會是在這層負責接應相對應的路由。
Controller 接收的是 Parameter
,輸出的是 ViewModel
。
Service
在我們程式中最重要的就屬於『商業邏輯』了,這一層是會特別關注的一層;這邊大家可能會問,那商業邏輯是指哪些呢?
我自己認為最簡單分辨的方式,舉凡任何需要對資料特別處理的地方都會是放在這一層,如常見的:登入驗證、加減法運算、確認是否驗證成功…等。
Service 接收的是 InfoModel
,輸出的是 Dto
。
Repository
資料倉儲層,這層主要處理『有關資料串接』的部分,如:資料庫連接、下 SQL 取 Table 資料…等,都會是在 Repository 處理。
這邊有個特別的地方,如果我們程式需要透過別人的 API 取的資料回來做處理呢?
那與對方 API 串接的地方就會是 Repository,所以 Repository 是處理『有關資料串接』的地方,而這資料當然並不只限於從 DB 撈取的資料。
Repository 接收的是 Condition
,輸出的是 DataModel
。
Common
共用層相對單純,存放各層間會用到的『共同』東西,最常見的例如:Enum…等,就會放在這一層。
常見問題
- 三層式架構與傳統 MVC 有甚麼不同呢?
傳統 MVC 分成,View(展示層)、Model(資料層)、Controller(控制層),這邊與三層式架構最大的區別在於傳統 MVC 並沒有特別把『商業邏輯』抽出來;常會看到傳統 MVC 可能會把商業邏輯附加在 Controller,所以 MVC 與三層式架構是不同的。
- 各層間溝通一定要透過 Model 嗎?
這個答案就我個人使用的理解是,『不一定要透過 Model』,如果只是要回傳簡單的 bool 、或是一兩個參數,直接傳就可以了;那做成 Model 的用意呢?當然也是為了提高重用性,例如 ResultModel。
|
|
雖然只有兩個變數,但還是把它包成了 Model ,因為有很多個地方會需要用到,當然就可以包起來給大家共同使用。
- Service 層可以呼叫其他 Service 層的程式嗎?
可以,三層式架構的優點就是要提供重用性,當然如果相同的事情在其他地方已經有做過了,直接拿來使用,就不用做重複的事情。
- Model 的名稱分了這麼多?不能直接一個通到底嗎?
這問題也是我一開始不太能夠理解的部分,如果是一個人寫程式的時候都會為了方便,就一個 Model 通到底吧;這時候肯定會有人問就算多人合作也可以啊?
真的可以嗎?
各層間的職責都不同,從 Reoisitory 取出來的資料丟給 Service 做處理,有可能不需要全部完整的資料回傳給 Controller,為了避免這種情況當然是分開會比較妥當,自己使用自己的 Model;多人合作的時候只需要定義說好相互要傳遞的參數就可以分層開發了,也不會因為一個 Model 而影響對方。
小結
當我是一個人開發的時候,分層設計真的感受不深,更多的是為何要弄得這麼複雜,但隨著工作團隊的擴展,多人合作開發的時候,分層設計就發揮出了它的價值,各個成員專注各自的層發開,不會被其他成員影響,當需要修改或擴充時,若是要改 UI,只需要異動展示層,若是新增商業邏輯則只需專注業務層,而是為要換第三方配合廠商或者更換資料庫,則只需專注在資料層去修改,而各層的物件又可以依不同情境做重用,不需重複開發,可謂好處多多。
效益:
- 適合多人團隊分工時不互相影響 (一條龍開發時感受不深)
- 分層專注,可以專注修改,不會牽一髮動全身
但真的能達到這樣的效益,其實還有一些必要前提:
- 物件設計須符合 SOLID 原則
- 各層依賴介面 (Interface),不依賴實作
- 專案需導入 DI Framework,做到依賴注入,達成控制反轉 (IoC)
- 撰寫單元測試 (Unit Test) 保護每次修改
- 合理的設計各層職責物件,業務層更為重要