49

我过去读过一些关于模型的 MVC 建议,指出您不应该为域和视图重用相同的模型对象;但我找不到任何愿意讨论为什么这很糟糕的人。

我认为创建两个单独的模型——一个用于域,一个用于视图——然后在它们之间进行映射会产生很多重复,加上繁琐的映射代码(其中一些可能会被AutoMapper之类的东西缓解),这很可能容易出错。

是什么让为这两个问题建立一个单独的模型值得重复和映射代码的麻烦?

4

7 回答 7

47

两个模型的核心是关注点分离。我希望我的视图可以使用单个模型。我希望我的领域模型能够代表我与领域专家建立的概念模型。ViewModel 通常有技术限制。域模型是关于 POCO 的,不受显示(视图)或持久化数据(在数据库中或其他地方)的技术约束的约束。

假设我在屏幕上显示了三个实体。这是否意味着我需要强制三者之间建立关系?或者只是创建一个包含所有三个项目的 ViewModel 组件对象。使用单独的 ViewModel,视图关注点与我的域分离。

于 2009-01-24T01:23:12.583 回答
7

为什么?因为视图不应该有使用模型对象的能力!

想象一下,您将项目传递给网页设计师来做视图层。突然间,他/她有能力通过模型层来处理应用程序的数据。这不好。

所以总是只传递视图需要的数据,而不是带有方法的对象。

于 2009-01-24T01:42:53.560 回答
5

JP Boodhoo 的文章Screen Bound DTO将帮助您了解设计优势。

还有一个我写过的安全好处。

拥有一个表示模型可以简化您的视图。这一点尤其重要,因为视图通常很难测试。通过拥有一个表示模型,您可以将大量工作移出视图并进入域->表示模型。诸如格式化、处理空值和展平对象图之类的事情。

我同意额外的映射是一种痛苦,但我认为您可能需要在您的特定环境中尝试这两种方法,看看哪种方法最适合您。

于 2009-01-24T00:46:39.460 回答
2

甚至还有更明显的问题,包括视图模型的特殊格式化能力和空值安全性。

于 2009-01-24T13:49:56.633 回答
1

我想这个想法是您的域模型可能会扩展到其他实现,而不仅仅是您的 MVC 应用程序,这会破坏关注点分离原则。如果您的视图模型是您的域模型,那么您的域模型有两个更改原因:域更改要求和视图要求更改。

于 2009-01-24T00:38:00.337 回答
1

似乎我也有重复的规则。

IE。UI 上的客户端对象验证,然后映射到必须验证的域对象。

然而,我倾向于做的是映射我的域对象集以创建模型 - 即。一个显示客户信息、库存信息等的网页……我的模型变成了一个包含 Customer 对象和 Stock 对象的结构。

公司页面模型

public Customer Customer{get;} public Stock Stock {get;}

然后在我的 mvc 项目 ViewData.Model.Customer.Name ViewData.Model.Stock.CurrentStocks

分离“似乎”需要更多的工作,但后来,最好有这种 UI/域模型的划分......有点像编写测试:)

于 2009-01-24T15:02:19.030 回答
0

我终于喝完了酷助手,我确实喜欢能够用显示说明标记我的视图模型,并让所有这些都自动连接起来。

我现在需要的是某种来自 poco 实体的视图模型的自动生成器。我总是将一些字符串设置为 int 并且我要花很长时间才能找到它。除非您喜欢痛苦,否则不要考虑在没有自动映射器的情况下执行此操作。

于 2011-10-09T03:15:08.517 回答