2011-02-01 70 views
24

我知道使用域模型作爲視圖模型可能不好。如果我的域模型具有一個名爲IsAdmin的屬性,並且我有創建控制器操作來創建用戶,則某人可以更改我的表單並將其發送到POST一個IsAdmin = true表單值,即使我沒有在我的視圖中公開這樣的文本字段。如果我使用模型綁定,那麼當我提交我的域模型時,該人現在將成爲管理員。因此,該解決方案只會暴露視圖模型中需要的屬性,並使用像AutoMapper這樣的工具將我的返回視圖模型對象的屬性值映射到我的域模型對象的屬性值。但是我讀過一個類的綁定屬性可以用來指示模型綁定器應該綁定哪些屬性。那麼究竟是什麼原因讓兩個不同的類(域模型和視圖模型)基本代表相同的事情,然後在映射它們時會產生開銷?這是更多的代碼組織問題,如果是的話,我如何從中受益?爲什麼兩個類,查看模型和域模型?

編輯

一個我遇到的視圖模型這是從域模型獨立的最重要原因是實現MVVM模式(基於Martin Fowler的PM模式),用於管理需要複雜的用戶界面。

+1

看看這個問題也太http://stackoverflow.com/questions/3094633/bestpractice-mixing-view-model-with-domain-model – 2011-02-01 17:40:36

回答

18

我發現,雖然我的域模型讓我有85%的方式擁有我想要的字段,但它從未覆蓋我想要的值的100%。特別是當涉及到權限以及用戶是否應該訪問視圖的某些部分時。

我試圖遵循的設計理念是儘可能少的邏輯。這意味着我的視圖模型中有「CanViewThisField」或「CanEditThisField」字段。當我第一次開始使用MVC時,我的域模型將成爲我的視圖模型,而且我總是碰到這種場景,我只需要一兩個字段就可以減少視圖的混亂。我已經走了View Model/Model Builder路線,它爲我工作的很好。我不再與我的代碼作戰,但能夠在不影響域模型的前提下增強我的視圖模型。

+0

我同意使視圖更少混亂,但我們不能抽象這種類型功能的域模型,而不是視圖模型?我早些時候說過,但是我不能在我的域模型上使用DisplayAddress()函數,它將結合像Address,City,State和Zip這樣的域屬性。數據庫只映射屬性而不是函數。 – enamrik 2011-02-01 20:30:19

+0

顯然任何事情都是可能的,只是取決於你想走哪條路。我爲我生成了我的域模型,所以我沒有真正觸及該代碼。如果您使用任何種類的ORM,那麼情況就是如此。視圖模型爲我提供了最大的靈活性,而且不會影響性能。 – 2011-02-01 21:14:50

+0

對不起,我沒有按照你給的鏈接到現在。我已經得出結論,決定是否採用域模型 - 視圖 - 模型路線取決於域模型的需求。我可以看到一些域模型對象如何使用視圖模型,而有些則不會(儘管這可能會讓某人感到困惑 - 我會更多地考慮它)。無論哪種方式,我都有我的答案。謝謝大家! – enamrik 2011-02-01 21:23:16

2

有時您需要以特定方式顯示數據(即以mm/dd/yyyy與yyyy/mm/dd的格式顯示日期),並且通常在視圖中製作此屬性更爲容易,不在域模型中,你可以(或者應該)在你的數據庫中有一個映射到列。

15

有一個ViewModel的另一個很好的理由是分頁大量的數據。您可以將視圖傳遞給Person數組(Person[]),但元數據(如頁數,當前頁數,頁面大小)不屬於Person類。

因此PersonListViewModel可以解決這個問題。

2

ViewModel僅包含視圖所需的那些成員。它們通常可以被認爲是基本域模型的簡化或「扁平化」。

他們這樣想:

  • 視圖模型:這是一個合適的渲染這個 觀點
  • 領域模型數據:這是我所有的應用程序需要 信息關於此實體以執行其所有功能

例如,我的Order類有一個叫客戶構件是composition的關聯,那就是我的訂單客戶。此客戶對象具有諸如名字,姓氏等成員......但是,我將如何在訂單的「詳細信息」視圖或訂單列表以及放置它們的客戶列表中顯示此信息?

那麼,使用一個ViewModel我可以具有其中有一個客戶名稱構件的OrderListItemViewModel,我可以名字和姓氏的組合從客戶對象到這個映射。這可以手動完成,或者最好使用Automapper或類似方法。

使用這種方法,你可以有多個訂單的ViewModels特定於不同的看法,例如訂單列表視圖可能以不同的方式呈現客戶名稱到訂單詳細信息視圖。

的ViewModels的另一個優點是,可以減少對在視圖上,例如不需要底層域對象的多餘的數據如果我正在查看訂單列表,我是否真的想看到所有客戶的聯繫信息,賬單細節等...?我想這取決於列表的目的,但可能不是。

2

你需要記住 您domain model classes僅用於internally;也就是說,它們絕不會發送到 客戶端。這就是您的服務模型類型(視圖模型類型)的用途 - 它們表示將在客戶端和服務之間來回傳輸的數據。