2011-02-01 91 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;也就是说,它们绝不会发送到 客户端。这就是您的服务模型类型(视图模型类型)的用途 - 它们表示将在客户端和服务之间来回传输的数据。