胖模型/瘦控制器與服務層[關閉]
多年來,我一直在使用 .Net 開發企業應用程序。我的應用程序通常有一個域模型,其中包含映射到 SQL DB 表的實體。我使用儲存庫模式、依賴注入和服務層。
最近我們開始研究 MVC 3 項目,我們爭論了把哪個邏輯放在哪裡。我遇到了瘦控制器/FAT 模型架構,想知道服務層如何適應
選項 1 - 模型與服務對話
控制器很薄,在模型上呼叫方法。模型“知道”如何從數據庫中載入自己並與儲存庫或服務通信。例如,customerModel 有一個 Load(id) 方法並載入客戶和一些子對象,如 GetContracts()。
選項 2 - 控制器與服務對話
控制器要求服務檢索模型對象。載入/儲存等邏輯在服務層。該模型是純實體模型,僅包含數據。
為什麼選項 1 是一個更好的選擇,尤其是當我們談論企業應用程序時,我的經驗告訴我要分離關注點,保持模型和控制器盡可能薄,並有專門的服務來處理業務邏輯(imcl。數據庫互動)
感謝所有建議和對良好資源的引用。
所有這些都取決於您的應用程序的意圖和要求。
也就是說,這是我對“中等規模”(不是本地餐廳,也不是 Twitter/Facebook)Web 應用程序的建議。
- 精益領域建模
幹 POCO 樣式的對象,最好對 Web 應用程序的 MVC 架構一無所知,以盡可能與您的特定實現保持鬆散耦合。甚至可以重新打包類庫以在外部應用程序中使用,例如通過 WCF Web 服務的 REST API )。
MVC 中的“模型”最準確地表示Controller 知道的模型,因此是用於 View 的模型。
在較小的(通常是教程)應用程序中,“應用程序/域模型層”的實體模型通常是控制器發送到視圖的相同實例化對象。
在較大的應用程序中,開發人員通常採用 MVVM 架構的原則並開始使用單獨的視圖模型對象。控制器通常呼叫與下面看不見的實體一起工作的中間層服務。在這種情況下,MVC 中的 M 最準確的意思是 View Model。 2. 健壯的服務層
這並不意味著肥胖的邏輯,而是精心編寫的單一用途服務。雖然在模型之外的服務中編碼業務邏輯比純粹的“OOP”更“程序化”,但它對鬆散耦合、測試和靈活部署(例如 n 層部署)有很大幫助。
在我個人的實踐中,我在數據層對服務進行編碼,我認為我對 POCO 對象的行為建模(持久性機制、低級別驗證等)和更高級別的服務(業務/工作流功能)更接近於MVC 機制。 3. 精益控制器
我確保我的控制器僅僅是教練,因為它既不是遊戲(服務)也不是玩家(實體模型或視圖模型),而只是決定誰扮演什麼位置以及做什麼遊戲。我的控制器做兩件事:
- 呼叫與實體/域模型互動的服務
- 為適當的視圖準備一個視圖模型。甚至經過身份驗證/授權的控制器操作也是通過注入的服務/屬性完成的。
編輯1:
請記住,這並不意味著您的實體/域模型是或必須是貧血的。歡迎使用 ORM、儲存庫和工廠、驗證或狀態機制。這僅意味著對於中等規模的應用程序,MVC 中的Model**表示用於控制器的模型,以移交給您的 View。
希望這一點能讓 Fowler 的使徒們平靜下來,他們認為貧血的數據模型是一種反模式。同時,它確實反映了比 OOP 稍微更程序化的角度,後者更純粹地將行為包含在建模類中。
沒有“終極真理”,但使用這種模式,您會發現建構、測試和部署應用程序很容易——同時保持大量的可重用性和可伸縮性。
編輯2:
也就是說,即使對於規模適中的應用程序,過度架構(書呆子組成的詞?)系統也太常見了。例如,用儲存庫模式包裝 ORM,然後編寫服務以使用儲存庫……所有這些都有助於關注點分離等,但如果您的項目不需要(並且不太可能很快需要) 這樣的東西,不要建造它。一起跳過儲存庫,針對 ORM 編寫瘦業務服務(例如查詢類),甚至讓您的控制器直接與它對話都沒有錯。這一切都取決於規模。
編輯 3:
我想指出,這個解釋和建議是針對像 ASP.Net 這樣的伺服器端 MVC 架構的上下文,而不是針對像 Knockout 或 Backbone 這樣的客戶端框架。