我可以想到一些单独的视图模型类层是一种好方法的情况,我将尝试用通用 ORM 工具和通用 MVC 框架来解释它们 - 请注意,这两者都不是案例特定于带有实体框架的 ASP.NET MVC 框架(甚至也不适用于 .NET 中的编程......)。
另外:请注意,在以下几段中,我仅专门指视图模型。我将在本文末尾解决诸如批量分配漏洞之类的问题。
原因 1:只给 View 层所需的数据,仅此而已
这是一个有点“纯粹”的目标——在真正的 MVC 应用程序中,视图层只能访问它目前需要的数据,而没有其他权限。视图模型对象现在成为从视图层到控制器的规范: “这是我需要显示您请求的视图的数据。” 为了遵守基本的 MVC 原则,您需要确保所有关于显示哪些数据的决定都由控制器做出。
换句话说,如果你想显示一个用户的名字和姓氏、用户名和图片,你不需要(或不想)给视图层一个对象,它也有关于用户密码、角色的信息(或者,取一些可能不那么敏感的属性,高度或中间名)。相反,您给视图一个对象,该对象具有名字、姓氏、用户名和图片的属性,而视图只决定如何呈现数据。这样,您就可以确定呈现什么数据的决定留在控制器层中。
原因 2:避免 ORM 工具的跟踪能力出现问题
一些 ORM 工具 - 甚至一些返回常规对象的工具1 - 使用非常复杂的方法来跟踪您从数据层获得的对象的更改,以便更轻松地更改记录。例如,您可能会从数据存储中获取一个对象,更改该实例的一些属性,然后调用save()
方法在其他地方,并且对象在数据库中更新。根据 ORM 工具,将您的 ORM 实体转发到视图层可能会产生任何范围的后果,从性能问题(最坏的情况:数据库连接保持打开)到不必要的影响(例如,视图层中的错误会更改数据存储)。为了避免这些,在将实体发送到应用程序管道太远之前,将您的实体重新映射到与您的 ORM 工具无关的“真正的常规对象”。视图模型是实现这一目标的一种(多种方式)。
请注意,这是否必要完全取决于您的 ORM 工具。我不太了解 Entity Framework 的内部工作原理,无法知道您是否需要关心 - 但在 EF 的(非常)早期版本中,这是一个问题,至少在不使用 Code-First 方法时是这样。
结论:你必须关心吗?
不,不一定。如果没有视图模型,您可能会做得很好,在这种情况下,它们只是另一层抽象,除了复杂性之外并没有真正为您的应用程序增加任何东西。这一切都归结为您的 ORM 工具是否对您的代码提出任何要求,以及您是否是“MVC 纯粹主义者”。
旁注:但是批量分配漏洞呢?
Queti-Mporta已经指出批量分配漏洞可能是一个问题。我同意这是一个严重的问题,但我不同意通过使用视图模型来解决它。
对我来说,视图模型是从控制器到视图的数据传输对象,帮助控制器整理和汇总应该显示的数据。为了避免诸如批量分配漏洞之类的问题,我通常使用编辑模型,它与视图模型非常相似,但方向相反——即控制器。不是每个人都做出这种区分——我不太在乎你是否这样做。但是使用这个词汇表,我建议在您让用户更改您的数据时始终使用编辑模型,并且仅在对您有帮助时才使用视图模型。
1在 .NET 中,通常称为“POCO”或普通旧 CLR 对象。Java 在 POJO(Plain Old Java Objects)中有它的等价物,如果你能想到一种可以在面向对象编程中使用的语言,那么该语言也有它的等价物。