三層架構 嚴格分層架構模式的特點是上層只能訪問相鄰的下層,其他層次間的調用都不允許。三層架構就是一種嚴格分層模式,它把職責劃分為界面展示、業務邏輯、數據訪問三層,還有一個業務實體,前面三層都要依賴它,所以它並不構成一個層。 三層架構的特點是一種面向過程的編程思想,特點如下: a. 業務實體類中基本上 ...
三層架構
嚴格分層架構模式的特點是上層只能訪問相鄰的下層,其他層次間的調用都不允許。三層架構就是一種嚴格分層模式,它把職責劃分為界面展示、業務邏輯、數據訪問三層,還有一個業務實體,前面三層都要依賴它,所以它並不構成一個層。
三層架構的特點是一種面向過程的編程思想,特點如下:
a. 業務實體類中基本上只有屬性沒有方法。
b. 業務邏輯層的類基本上只有方法沒有屬性。
c. 將數據表結構映射為業務實體類是一個慣用做法,以至於有人將其稱之為“傳統”。這樣的好處是只需要理解一套模型,能夠通過自動化工具從數據表直接生成業務實體,還能夠自然而然的通過自動化機制存儲與檢索業務實體。但對於複雜點的業務,這樣做就是絕大部分問題的根源。
d. 當業務膨脹起來,需要劃分模塊的時候,我們有個常用的變形:提取一個服務層出來,用來組合模塊間的交互,還為業務邏輯層提供了一個防腐層,可以把記錄日誌、驗證許可權、處理異常等職責分配給服務層。
由於採用了嚴格分層模式,用戶界面層是絕對不能跨過業務邏輯層調用數據訪問層的,同理服務層也是不能調用數據訪問層。但是圖2都有四層了。
其實三層架構還有個更準確的名字----分層貧血領域模型架構,前面名字中的領域模型指的是業務實體,貧血意思業務實體中沒有或很少方法。
三層架構的反思
三層架構的最大問題在於:實際應用中人們喜歡把記憶體模型和資料庫模型保持一致。三層架構的大部分問題都是從這裡衍生出來的。
資料庫模型的粒度如果很小,那麼大量的表連接很快就會讓資料庫跑不動了。
如果資料庫模型的粒度如果很大(這是大部分項目的選擇),代碼的質量(重用性、穩定性、擴展性)就很差。由於沒有從業務的角度去仔細定義每一個對象,每個人會根據自己的需要建立各種QueryModel或ViewModel,慢慢地類會多到想哭。
還有一些三層開發人員最終患上了資料庫痴迷症,他堅信程式就應該做個搬運工,其他的事情都應該交給資料庫來完成,業務邏輯也應該寫進存儲過程裡面去。
三層分層到DDD分層的轉變過程
優化三層結構&重構到面向對象的設計
由於目前的服務層職責是非常輕的,甚至有很多空殼的調用,所以平衡一下職責,把調用數據訪問層的職責從業務邏輯層提升到服務層,需要的數據通過參數傳遞給業務邏輯層。這樣,對於那些簡單到無業務邏輯的CRUD就不需要去訪問業務層了,直接調用數據訪問層。
結構如圖3,我們看到業務邏輯與數據訪問層已經沒有依賴關係了。
然後我們就可以把業務邏輯與業務實體移到一塊。
然後把屬於業務實體的邏輯遷移到實體類中。
圖4基本上就是圖3的各個層換了名字,並且UI可以訪問基礎設施層。而圖4與圖5的區別在於,圖4是基礎設施依賴領域層,圖5是領域層依賴基礎設施層。
用戶界面層:
原版----負責向用戶展現信息以及解釋用戶命令。
補充---- MVC中V和C都屬於UI層,V展現信息,C解析用戶命令。UI像地圖一樣把各個控制器關聯了起來。
應用層
原版----很薄的一層,用來協調應用的活動。它不包含業務邏輯。它不保留業務對象的狀態,但它保有應用任務的進度狀態。
補充----協調應用的活動這句話太抽象了,我充實一下它:從數據訪問中獲取領域對象,調用領域對象的方法完成任務,然後再調用數據訪問代碼把領域對象的改變持久化。事務、許可權檢查、記錄日誌、處理異常的職責也歸它管。這點和前面三層的服務層的職責其實是一樣的。
領域層
原版----本層包含關於領域的信息。這是業務軟體的核心所在。在這裡保留業務對象的狀態,對業務對象和它們狀態的持久化被委托給了基礎設施層。
補充----業務對象的持久化工作我們已經提升到應用層了,一般情況下,這層最好不要涉及資源庫的調用,但是並不絕對。資源庫的抽象要麼在領域層中,要麼提升到了“應用程式框架”,領域層是不會依賴基礎設施的。
基礎設施層
原版----本層作為其他層的支撐庫存在。它提供了層間的通信,實現對業務對象的持久化,包含對用戶界面層的支撐庫等作用。
對比三層分層與DDD分層
a. UI層技術基本一樣,一些比較智能的綁定可能無法進行了。
b. 服務層基本一樣。
d. 業務實體+業務邏輯 = 領域層
e. 如果三層架構不採用業務實體與數據表一致的做法,這層也是一樣。由於記憶體結構與數據表結構之間存在阻抗失配,存取領域對象沒那麼簡單。
參考資料
《領域驅動設計精簡版》