2

所以我的编程背景是非常自学和零星的。我正在做一个 MVC4 项目,并试图专注于最佳实践,而不仅仅是功能。

该项目的一般意义是一个报告生成器。因此,我试图了解域模型与视图模型到底是什么,以及它们与用于 CodeFirst 实体框架的模型有何关系。任何提示表示赞赏。

根据我的理解,假设我的 Report 对象有多个属性,但是对于视图我只希望用户能够编辑某些属性,那么 ViewModel 将是 Report 对象和用户输入之间映射的东西?

4

3 回答 3

5

听起来你的想法是对的。AViewModel是域实体的视图表示。这可以应用于传入模型的数据和传出模型的数据。

但是,额外的层(和映射)也增加了代码的复杂性。您现在需要一个视图模型类、一个映射器类和一个域实体 (EF)。所以,如果你可以在没有这个额外层的情况下构建你需要的东西,那就保持简单。领域模型和领域建模只能用于非常复杂的业务领域。

于 2013-05-08T20:19:55.197 回答
2

是的,你的理解是正确的。

视图模型是视图使用的数据对象。它包含向用户显示某些数据或从用户那里收集数据所必需的属性。这些属性不一定只是数据。例如,您可以使用一些属性来控制是否启用或禁用输入表单中的任何字段。

另一方面,域模型是用于您的逻辑和持久性的对象。同样,它不一定只包含持久属性。可以有从持久属性计算的其他属性,也可以有在属性之上工作的方法。

在一些非常简单的场景中,视图模型和域模型可以由同一个对象表示。

于 2013-05-08T20:19:09.300 回答
2

这是我在几个示例中看到的,过去几年我一直在使用并且感觉很舒服的模式,也是我最近一份工作时已经存在的 MVC 团队已经在使用的模式。

基本上,实体框架或您使用的任何 ORM 都将具有实体类。这些要么是简单的 POCO,要么是带有一些 ORM 的更重的东西。目标是让实体之间的关系与现实非常相似,因此它们在某种程度上是您的“领域模型”。无论哪种方式,您经常会发现您的视图需要展平子/父对象的属性,或者如您所述,只显示某些字段。

通常,您还需要视图模型上的其他字段。例如,下拉列表的选项,因为它们不是实体的一部分(只有指示选择了哪个项目的外键在实体中,而不是用户可以从中选择的项目列表)。

因此,除非您的视图足够简单以能够使用 EF 实体的 @model,否则您通常可能需要一个 ViewModel(VM) 类。有些人对每个视图都有不同的虚拟机。我个人尝试重用我的虚拟机。通常是一个 PersonSummaryViewModel,它只有几个字段,适用于空间有限的选择列表或索引,我只会显示重要字段,以及一个 PersonViewModel,它是实体的所有字段,以及下拉列表的项目字段(但当在只读页面上使用时,它们只是留空)。

我个人喜欢将事物命名为 PersonVM 和 PersonSummaryVM,但其他​​人更喜欢对 PersonViewModel 进行更详细的命名。EF 会给您的实体名称,如 Person,但我看到其他 ORM 框架将所有类都以 Entity 为后缀,因此您拥有 PersonEntity。我个人开始喜欢实体后缀。

如果您的数据库设计得很好,那么您的实体类很可能与某些人认为的域模型非常接近。

我们有公开静态方法的类,我们调用这些方法来检索数据。控制器中几乎没有数据库代码,而是所有这些都在负责查询数据库的 PersonModelFactory.GetList()、PersonModelFactory.GetSingle(int id)、.Save(PersonVM person) 等静态方法中,以及将实体中的数据填充到视图模型中,然后返回视图模型。这些方法还执行某些验证(除了您可以对视图模型上的数据注释执行的基本操作之外)和其他业务逻辑,如果它应该与正在发生的任何数据库修改一起发生。那里' 更多的是涉及接口和泛型参数的实现细节,旨在使这些方法非常可重用,但对于本文的范围来说有点复杂。我们实际上已经成功地从 Web 表单和 MVC 中重用了这些类,因此它们证明了它们的可重用性。有些人不喜欢 DB 访问、映射和业务逻辑/验证发生在同一层的事实,但由于除非验证通过,否则不应发生 DB 修改,我们认为这些事情必须是原子的,并且相互依赖。

人们可能更常见的是使用 MVC 的数据库访问层的“存储库模式”,甚至还有 MVC 的脚手架可以为您生成这些类。但是,这些通常不会处理映射或业务逻辑。

无论哪种方式,主要目标是重用并最大限度地减少控制器操作中的混乱。在采用我提到的因子模式之前,我发现我的控制器变得杂乱无章。我看到了在动作之间重用代码的机会,因此我在控制器中创建了私有方法。我真的很喜欢我所在的团队现在更多使用的工厂模式。

您肯定会发现人们使用视图模型和存储库的方式有很多变化。

我不记得在 MVC 的上下文中看过任何专门谈论“域模型”的文章或示例。IMO 领域建模是需求收集过程的一部分,然后数据库/实体框架的设计将反映这些发现的结果。鉴于时间/资源/复杂性的限制,您可以简化域模型。有些框架可以处理诸如领域语言之类的事情,我认为这种事情并不常见。

在 ORM 出现之前,有人在数据库层(由运行 SQL 的命令对象组成)之间手动进行大量映射,到通常是 POCO 的“业务对象”,基本上是您作为 EF 实体所拥有的,但有时他们有一些业务验证/逻辑以某种方式合并。现在我几乎没有听到人们谈论“业务对象”,因为该层所服务的目的大多已被 EF 取代,而业务逻辑要么在控制器操作中,要么在其他一些服务层中。

多年来,有一点是肯定的,“视图模型”、“业务模型”、“实体”和“领域模型”对不同的人意味着什么会有所不同。

于 2013-05-08T20:52:53.547 回答