【问题标题】:DTO = ViewModel?DTO = 视图模型?
【发布时间】:2009-12-30 19:42:42
【问题描述】:

我正在使用 NHibernate 来持久化我的域对象。 为简单起见,我将 ASP.NET MVC 项目用作我的表示层和服务层。

我想从我的控制器类中以 XML 格式返回我的域对象。在阅读了 Stack Overflow 上的一些帖子后,我认为 DTO 是要走的路。不过,我也遇到过有关 ViewModel 的帖子。

我的问题:数据传输对象和视图模型是一回事吗?还是 ViewModel 是 DTO 的一种子模式?

【问题讨论】:

  • 我认为有必要提及 ASP.NET MVC 中的 ViewModels 与 WPF (MVVM) 中的 ViewModels 不是 100% 等效,因为大多数答案都提到了 MVVM 并且您正在使用 ASP.NET MVC。

标签: asp.net-mvc domain-driven-design viewmodel dto


【解决方案1】:

DTO 的规范定义是没有任何行为的对象的数据形状。

ViewModel 是视图的模型。 ViewModel 通常是来自一个或多个对象(或 DTO)的全部或部分数据以及特定于视图行为的任何其他成员(可以由视图执行的方法、指示如何切换视图元素的属性等)。您可以将视图模型视为视图和行为的所有数据。 ViewModel 可能会也可能不会一对一地映射到业务对象或 DTO。

顺便说一句,如果某个视图模型需要来自持久对象的数据子集,NHibernate projections 会派上用场。

【讨论】:

  • 你能解释一下吗:“DTO 是没有任何行为的对象的数据形状”?
  • 意思... DTO类通常只包含属性,不包含任何具有业务逻辑等的方法...
【解决方案2】:

ASP.NET MVC 实践中的 ViewModel 与 DTO 相同,但 MVVM 模式中的 ViewModel 与 DTO 不同,因为 MVVM 中的 ViewModel 有行为,而 DTO 没有。

【讨论】:

  • asp.net mvc中的ViewModel为什么要和DTO一样?这是没有意义的。 ViewModel 可以具有 DTO 没有的行为。这不依赖于 mvc。
  • +1 用于区分 ASP.NET MVC ViewModel 和 MVVM ViewModel。
  • @Elisa - 您相当老的问题的答案是,在 ASP.NET MVC 中,视图调用控制器(不是 ViewModel)上的操作,以便以无状态方式更改模型和视图.因此,形成视图的 DTO 本质上与 ViewModel 相同。但是,在具有另一个序列化边界的大型系统中,如果将 DTO 与专门为 View 设计的 ViewModel 分开,那么 DTO 可能会有所帮助。
【解决方案3】:

DTO != ViewModel

MVVM 模式中,ViewModel 用于将模型与视图隔离开来。为了表示模型​​,您可以使用简单的DTO 类,它再次通过例如映射到数据库。休眠。但我从未见过被建模为 DTO 的 ViewModel 类。ViewModel 类大多具有 DTO 所没有的行为。

【讨论】:

  • 所以 DTO 可以只是结构(或者是一个应该模仿结构功能的类)?
【解决方案4】:

DTO - 数据传输对象正如它所说的,用于传输数据的容器。他们没有行为,只有一堆 setter 和 getter。有些人使它们不可变,只在需要时创建新的,而不是更新现有的。它们应该是可序列化的,以允许通过网络传输。

通常 DTO 用于跨进程边界将数据从一层传送到另一层,因为调用远程服务的成本可能很高,因此所有需要的数据都被推送到 DTO 并以一个块的形式传输到客户端(粗粒度) .

但是,有些人使用屏幕绑定 DTO 的概念(与跨进程边界无关)。同样,这些填充了所需的数据(通常是特定屏幕所需的数据,可能是来自各种来源的数据的聚合)并发送到客户端。

http://blog.jpboodhoo.com/CommentView,guid,21fe23e7-e42c-48d8-8871-86e65bcc9a50.aspx

如前所述,在简单情况下,此 DTO 可用于绑定到视图,但在更复杂的情况下,它需要创建 ViewModel 并将数据从 DTO 卸载到 ViewModel,这显然需要更多工作(当应用MVVM 模式)。

同样如前所述 DTO!=ViewModel

DTO和ViewModel在生活中有不同的用途

【讨论】:

    【解决方案5】:

    首先,主要区别在于 ViewModel 可以具有 DTO 不能有的行为或方法!!!

    其次,在 ASP.NET MVC 中使用 DTO 作为 ViewModel 会使您的应用程序与 DTO 紧密耦合,这与使用 DTO 的目的完全相反。如果这样做,使用域模型或 DTO 有什么区别,获得反模式的复杂性更高?

    ASP.NET 中的 ViewModel 也可以使用 DataAnnotations 进行验证。

    同一个 DTO 可以有不同的 ViewModel 映射,一个 ViewModel 可以由不同的 DTO 组合而成(总是使用对象映射而不是组合)。因为我认为如果你有一个包含 DTO 的 ViewModel 会更糟,我们也会遇到同样的问题。

    从您的表示层,将 DTO 视为一种合同,您将收到一个您必须将其视为对您的应用程序陌生的对象,并且无法对其进行任何控制(即使您拥有前服务,dto和表示层是你的)。

    最后,如果您进行这种干净的分离,开发人员可以轻松地一起工作。 设计 ViewModels、Views 和 Controllers 的人不必担心服务层或 DTO 实现,因为当其他开发人员完成他们的实现时,他将进行映射...... 他甚至可以使用 Mocking 工具或手动模拟来填充表示层以进行测试。

    【讨论】:

    • 我刚刚安装了 VS 2012 并查看了 MVC 4 Single Page Application。在示例项目中,DTO 用作 WebApi 中控制器方法(或操作)的参数。换句话说,JSON 被发布到这些方法中,并且通过一些 MVC 魔法,数据在传递给方法之前会自动转换为 DTO。您是否认为在这种情况下使用 DTO 是错误的。 ViewModel 是否应该与 Web API 一起使用?我要求更好地理解,因为我对这些概念还不是很熟悉。
    • Salut Jean-François Beauchamp :) ASP.NET MVC 可以将 url 婴儿车解析为一个对象,例如:假设我有这个映射到索引方法 ajax/index/{jobID}/{ResultsToSkip} /{ResultsToSend}" 而不是在控件中 Index(int jobID, int ResultsToSkip, int ResultsToSend) 我将拥有 Index(request) (request 是一个封装 3 个字段 jobID ...的对象)所以现在你不是 params使用封装 DATA 的对象与您的应用程序交谈,所以是的,我们可以说 requestDTO。例如,您必须添加一个其他字段,您只更改 DTO,而不是 api 接口方法。
    【解决方案6】:

    对于一些简单的视图,我将使用我的 DTO 作为我的模型,但随着视图变得更加复杂,我将创建 ViewModel。

    对我来说,这是快速(使用 DTO,因为我已经拥有它们)和灵活性(创建 ViewModel 意味着更多关注点分离)之间的平衡。

    【讨论】:

    • 不错的务实答案。
    【解决方案7】:

    如果您需要更改或增强 DTO,请创建一个 ViewModel。 ViewModel 也可以将 DTO 作为复杂属性引用。

    在实践中,您通常希望将特定于视图的属性或方法添加到您在视图中使用的模型中。在这种情况下, 永远不要根据您的视图要求修改 DTO。相反,创建一个 ViewModel 并将您的 DTO 映射到 ViewModel。

    【讨论】:

      【解决方案8】:

      如果您将 DTO 用作 ViewModel,这意味着您对 DTO 的依赖度很高,因为某些原因您正在更改 DTO,那么它可能会影响 ViewModel。

      更好地使用 DTO 并转换为视图模型。

      【讨论】:

        【解决方案9】:

        我们可以使用与Model类相同的DTO,当我们需要在单个视图中显示/使用多个模型数据/属性时,我们可以使用viewmodel。示例:我首先使用实体​​框架数据库创建了一些模型。所以,现在所有的模型都是基于数据库生成的。现在我们需要数据注释,对于这些数据注释,我们可以创建一个名为 DTO 的文件夹,在这个 DTO 文件夹中,我们可以保留所有已经生成的模型,并在属性上方添加数据注释。然后我们可以使用这个 DTO 类进行任何操作(使用控制器、视图)。当我们需要复杂的视图时,我的意思是当我们需要一个视图中的多个类数据时,我们可以使用 viewmodel。对于 viewmodel,我们可以创建一个文件夹名称 viewmodel,然后创建一个自定义类并保留我们需要的属性。我试图清除自己。任何建议高度赞赏。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-25
          • 2011-02-10
          • 1970-01-01
          • 2021-06-30
          相关资源
          最近更新 更多