一、為什么要分層
分層架構是所有架構的鼻祖,分層的作用就是隔離,不過,我們有時候有個誤解,就是把層和程序集對應起來,就比如簡單三層架構中,在你的解決方案中,一般會有三個程序集項目:XXUI.dll、XXBLL.dll 和 XXDAL.dll,然后把這三個程序集看成一個層,這沒什么不可以,但當項目復雜的時候,如果還按照這種方式的話,你的程序集中的文件夾會越來越多,程序集也會越來越大。當你的視野跳出這個程序集的概念后,你會發現,層不只是和程序集對應,也和解決方案文件夾,或者是整個解決方案對應,一個層甚至可以對應一個系統。
分層的目的即為了“高內聚低耦合”的思想。
二、微軟經典的三層架構
任何一個.net都知道的微軟的三層架構,三層架構就是把業務划分為界面層(User Interface layer)、業務邏輯層(Business Logic Layer)、數據訪問層(Data access layer)。如下圖
各層的作用:
界面層(UI):主要表示WEB方式,也可以表示成WINFORM方式;如果邏輯層相當強大和完善,無論表現層如何定義和更改,邏輯層都能完善地提供服務。主要對用戶的請求接受,以及數據的返回。
業務邏輯層(BLL):主要是針對具體的問題的操作,也可以理解成對數據層的操作,對數據業務邏輯處理,如果說數據層是積木,那邏輯層就是對這些積木的搭建。
數據訪問層(DAL):主要看數據層里面有沒有包含邏輯處理,實際上它的各個函數主要完成各個對數據文件的操作。而不必管其他操作。
在開發人員眼里,一個業務系統的分層只是技術架構上的,所以會把日志紀錄、權限管理、數據庫持久化、消息服務等等,把一些能分離出來的盡量分離出來,然后再把這些東西組合起來,就成了系統幫助層,它們貫徹於整個業務系統。
三層架構是典型事務腳本邏輯結構,一個復雜的業務都在BBL方法體中從頭到尾描述,處理高度復雜的業務顯得無能為力!!!
估計所有的.NET 程序員都是從這個經典的三層的架構一步一步走過來的。
三、DDD經典分層
DDD:領域驅動設計
TDD:是測試驅動開發
POEAA:企業應用架構模式
DDD核心思想是由業務問題來控制解決方案的形式從以數據庫為中心過渡到領域模型為中心
下面這個圖是我在《領域驅動設計與模式實戰》書中拍下來的,他完全詮釋DDD的經典分層。
各層概念:
表現層(Presentation Layer):圖中的用戶界面層包括用戶接口層,用戶輸入和數據展示。
應用層(Application Layer):應用層定義系統的業務功能,並指揮領域層中的領域對象實現這些功能。
領域層(Domain Layer):核心層,實現所有業務邏輯。
基礎設施層(Infrastructure Layer):提供整個業務系統的基礎服務。
各層在編譯時的類依賴關系如下圖(這是一個很矮矬窮的圖):
高層模塊不應該依賴於底層模塊,兩者都應該依賴於抽象
抽象不應該依賴於細節,細節應該依賴於抽象。
四、ABP分層
上節FirstABP的解決方案:
ABP詳細分層:
我們從上到下看看都是什么意思:
表示層
Presentation:
View Models (Javascript):=
Views (HTML/CSS):=
Localization, Navigation, Notifications:多語言,菜單,通知
web:
Web API Controllers:webapi接口
MVC Controllers, OData:OData是什么我也不知道
應用層(Application)
Application Services:應用服務
DTOs:數據傳輸對象
DTO Mappers:AutoMapper進行實體與DTO之間的映射
Authorization:參數驗證
Session:
Audit Logging:審計日志
應用層提供一些應用服務(Application Services)方法供展現層調用。一個應用服務方法接收一個DTO(數據傳輸對象)作為輸入參數,使用這個輸入參數執行特定的領域層操作,並根據需要可返回另一個DTO。在展現層到領域層之間,不應該接收或返回實體(Entity)對象,應該進行DTO映射。一個應用服務方法通常被認為是一個工作單元(Unit of Work)。用戶輸入參數的驗證工作也應該在應用層實現。ABP提供了一個基礎架構讓我們很容易地實現輸入參數有效性驗證。建議使用一種像AutoMapper這樣的工具來進行實體與DTO之間的映射。
領域層(Domain(Core))
Entities:實體,領域對象,代表業務領域的數據和操作
value objects:實體模型
Repositories:倉儲,用來操作數據庫進行數據存取。倉儲接口在領域層定義,而倉儲的實現類應該寫在基礎設施層。
Domain Services:領域服務,當處理的業務規則跨越兩個(及以上)實體時,應該寫在領域服務方法里面。
Domain Event:領域事件,在領域層某些特定情況發生時可以觸發領域事件,並且在相應地方捕獲並處理它們。
Unit of Work:工作單元,一種設計模式,用於維護一個由已經被修改(如增加、刪除和更新等)的業務對象組成的列表。它負責協調這些業務對象的持久化工作及並發問題。
基礎設施(Infrastructure)
ORM (EntityFramework, NHibernate):ORM框架,ABP提供了EF和NHibernate支持
DB Migrations:EF Code First創建數據庫用的
Background Jobs:作業調度和自動任務,(類似Quartz.NET)
補充(單頁面應用和多頁面應用)
在單頁面應用中(SPA),所有的資源都會一次性加載到客戶端(或者只加載核心資源,懶加載其他資源),所有的后續和服務器的交互都是通過Ajax調用。Html代碼是使用從服務端接收到的數據在客戶端生成的。整個頁面不會刷新,視圖只是在必要時換入換出。有許多的Javascript SPA框架,比如AngularJs,DurandalJs,BackboneJs和EmberJs。ABP可以使用它們中的任何一個,但是提供了使用 AngularJs和DurandalJs的樣例。
在多頁面(經典)應用中(MPA),客戶端向服務端發送請求,服務端代碼(ASP.NET MVC 控制器)從數據庫中獲取數據,然后Razor視圖引擎生成html 代碼。這些編譯后的頁面發回給客戶端顯示。每個新的頁面都會導致完整頁面的刷新。
SPA和MPA涉及了完全不同的架構。對於后台管理系統來說,SPA是最好的候選者,另一方面,博客更適合MPA模型,因為博客渴望被搜索引擎抓取數據。雖然有很多工具可以使SPA對於搜索引擎可見,但是目前的一般做法就是使用MPA。
最后
ABP平衡了一些最好的框架或者類庫,除此之外,ABP自己的類和系統也提供了一個很好的用於N層架構Web應用構建的基礎設施,也提供了很輕松地創建分層的解決方案的模板,用作應用的起點。
根據分層我們把項目的類庫用解決方案的文件夾整理下: