2012-12-10 57 views
3

在上週的工作中,我們舉行了關於重新思考我們如何進行MVC的會議/演示,其依據的是我們的老闆可能進行的大量研究以及一些其他SO問題的解讀。對我來說一個要點是,當人們說「與數據分開的邏輯」時,我可能會更準確地說出「與您的數據分開的邏輯」。如果你先做,你可能會陷入貧血域模型。我在這裏糾正?MVC應用程序,這個邏輯屬於哪裏?

其次,我們瞭解到,MVC不包含任何地方的業務邏輯。除了Web應用程序之外,它應該位於單獨的服務層或BLL中。協調這兩點似乎有點棘手 - 按照基本的OOP原則規定,還是在單獨的層中,是否有特定的邏輯與數據對象一起使用?

以下是我現在需要幫助的具體示例。我相當確信這屬於服務層,但我仍然有其他問題。比方說,我有一些行爲需要輸入多個不同類型的不同實體。它運行,然後作爲輸出,它可以修改輸入實體,並生成新的實體作爲記錄。在我的情況下,這是一個遊戲,但你可以說它就像一個交易。涉及多個人員,一些產品和收據。

  1. 容易的問題,你會把這個邏輯放在哪裏?它是一個獨立的類被實例化嗎?
  2. 難題(對我而言)是誰負責調用這段代碼?讓控制器執行它會感覺不對。或者完全是它的工作?如果它不能在任何一個特定頁面上運行,但是每當用戶在特定時間之後訪問該站點時該怎麼辦?基礎控制器?
  3. 一般來說,你如何決定「這屬於我的實體類,以便它不僅僅是一堆吸氣器和二流子」,「這屬於我的服務層」?還是我混淆了......實體類是否屬於服務層?

回答

4

讓我們先解決一些術語。正如你所說,你所說的「服務層」通常被稱爲「域模型」,不要與MVC模型混淆。在最基本的層面上,MVC模型封裝了領域模型。如何將兩者相互不被圖案本身定義,但這些模型存儲的狀態的邏輯方法是實現有兩種不同的狀態:

  • 在現實世界中的域國有這將更多的往往不是以某種方式存儲在數據庫中,但域模型不應將任何數據源公開給MVC模型。這允許域模型保留適當的封裝。任何改變或訪問這些數據的邏輯都應該在這裏用MVC模型訪問的相關但抽象的訪問器完成。

  • 應用程序狀態 - 即「正在編輯哪個記錄?」

要回答你的問題,這真的取決於你在做什麼與數據。如果你正在做任何類型的處理,那麼這應該在領域模型中完成。如果您只是獲取顯示所需的數據集合,那麼MVC模型應該查詢域模型以檢索相關數據。然後該視圖應該查詢該數據的模型。

因此,要回答你的問題:

  1. 在thisspecific情況:其處理數據應該是域模型內的交易。它可以直接訪問所有相關數據,只需使用任何必需的參數即可調用。這促進了可重用性,因爲它不直接與MVC模型綁定。
  2. 從技術上講,如果你的控制器直接訪問域模型,它比MVC更接近MVVM實現。然而,這並不是一件壞事,只要你的領域模型的參數與領域邏輯沒有關係,那就不是真正的問題。但是,控制器不應構建域對象(例如,創建用戶帳戶並將其傳遞給模型)。擁有MVC三元組之外的領域模型的原因正是:因此,調用代碼並不重要,領域邏輯與其運行的架構無關。這是一件好事。 MVC是呈現的,有時候域邏輯就是數據處理。關於「每當用戶在特定時間之後訪問該網站」,這是領域邏輯,因此應該在領域模型中進行。在哪裏取決於究竟是什麼觸發事件,但在這種情況下,它可能是登錄例程或類似事件的一部分。
  3. 確實。這些實體(我假設你指的是指單個域對象,用戶,產品,博客等的對象?)可能本身不包含太多邏輯,因爲它們大多數是數據結構。一個訂單可能有一個「getProducts()」或「getDeliveryAddress()」,它提取相關的實體,但是域模型會對數據本身做任何處理。

作爲一個經驗法則,幾乎所有能夠改變數據或處理來自多個實體的數據的邏輯都應該發生在域模型中。這主要有兩個原因:1.可重用性,邏輯可以從任何地方重用。 2.封裝。一旦你開始把這個邏輯放到實體中,你最終會遇到一種情況,即域實體依賴於其他域實體。這會導致在現實世界中非常脆弱的代碼,因爲最終導致任意規則在以後引入,例如「這些客戶不必輸入付款詳細信息」。 「如果你已經建立了對」訂單「類的建模依賴於一套或多個產品的用戶和賬單地址,這是一個公司客戶,他們沒有賬單地址」,這成爲一個比處理更大的任務在領域模型的早期階段。

相關問題