前幾天,有園友私下問我,博客中的AccountDemo後端架構爲何是那樣的,是否是分層太多太冗餘,故這裏簡單介紹下。先看解決方案工程截圖:html
每一個工程的含義,見https://www.cnblogs.com/guokun/p/7082987.html。運行時,請求處理流程,這裏再貼出來:數據庫
這裏,園友主要不解的是,爲何會有兩個接口層,Account.Repository.Contract和Account.Service.Contract,是否是太多了。最近幾年,在後端架構中,出現了一種稱之爲六邊形架構的架構模式,這貨以前曾被叫作洋蔥架構、端口適配器架構,反正你們知道都是它就是了。六邊形架構的核心,就是應用程序業務邏輯處於架構的核心,而上層的視圖、控制器、數據訪問等,都屬於基礎設施,是用來輔助實現業務邏輯的,他們都依賴於核心業務邏輯。這些基礎設施是易變或者說極可能被頻繁替換的,例如應用層今天多是MVC,明天多是WebAPI,數據訪問今天多是EF,明天多是Dapper,甚至CSRedis,MongoDB。。。編程
六邊形架構最終要實現的效果就是,解耦應用核心業務邏輯與基礎設施,其總體架構與依賴以下圖:後端
藍色箭頭方向表明依賴方向,而非運行時數據流向或請求處理流向,請特別注意。ApplicationCore處於整個架構的中心,周邊都是依賴於它的,這也是這一層名稱ApplicationCore的由來,其核心特徵是:一、用用層及基礎設施層都依賴核心業務層;二、業務邏輯保持不變,應用層或基礎設施層,好比切庫、切ORM、切應用層框架,隨便搞;三、有別於傳統三層架構,數據層提供什麼,業務層就有什麼或用什麼,六邊形架構是業務層須要什麼,就定義什麼契約,數據層就實現什麼或提供什麼。架構
介紹完了六邊形架構,接下來回答,爲何有兩個接口層。本質上,Account.Repository.Contract和Account.Service.Contract兩層契約均歸屬於核心業務層,Account.Service.Contract用於對應用層承諾,提供什麼服務,Account.Repository.Contract和Account.Service.Contract則規定基礎設施層必須給本身提供什麼操做。若是你願意,那麼這兩個接口層徹底能夠融入Account.Service工程中,這都是沒問題的,原本他們就屬於業務邏輯的範疇,但我仍是把它單獨分出來,不然即是應用層、基礎設施層直接硬依賴Account.Service,一者過重,兩者不符合將面向接口編程。app
最後,說下,爲何Account.Repository.EF倉儲工程中,一個實體類,對應了一個倉儲對象。嚴格來說,這麼作是不合適的,設想一下,假如數據庫表不少,那這裏豈不膨脹得厲害。要弄明白這個問題,首先得知道倉儲的由來。這玩意兒來自領域驅動架構,通常來說,一個倉儲是一一對應一個聚合根,這個聚合根是業務上功能聚合的一系列領域對象的,例如一個學生,對應一個宿舍,同時這個學生是個高富帥,他他媽的比較花心,身邊有N個白富美女友。若是系統要維護這麼樣一個對應關係或信息,這裏學生就是一個聚合根。具體表如今代碼中,直觀看就相似一個複雜對象,這個複雜對象的最外邊就是學生,裏邊嵌套啥宿舍啊,女友集合啊,什麼的。正常狀況下,應該是學生這個聚合根纔對應一個倉儲類的,什麼宿舍,女友都不該該有倉儲類(假設沒有其餘需求致使他們須要上升爲聚合根)。解釋完了聚合根,這裏回到剛纔那問題,爲何搞成了一個數據庫實體一個倉儲類。主要在於,示例中抽象出了這麼一個倉儲基類:框架
這玩意兒是泛型的,由於後續倉儲實現類想要用到其中的一些公用方法,實現這個基類時候,須要約定實體,因此爲了偷懶,我就每一個數據庫表或者領域實體一個倉儲類了,僅此而已。htm
好了,園友提到的幾個問題差很少就這樣。對象