DTO = ViewModel?

我使用NHibernate来坚持我的域对象。 为了保持简单,我使用ASP.NET MVC项目作为我的表示层和我的服务层。

我想从我的控制器类返回我的域对象的XML。 在阅读堆栈溢出的一些post后,我收集DTOs是要走的路。 不过,我也遇到过有关ViewModel的post。

我的问题是:数据传输对象和ViewModel是一样的东西? 或者是ViewModel是DTO的一种子模式?

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

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

顺便说一下,如果某个视图模型需要持久化对象的数据子集,那么NHibernate 投影就派上用场了。

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

DTO!= ViewModel

在MVVM模式中,ViewModel被用来将View从模型中分离出来。 为了表示模型​​,你可以使用简单的DTO类,它们又通过例如NHibernate映射到数据库。 但我从来没有见过一个ViewModel类被build模为一个DTO .. ViewModel类主要有行为,DTOs没有。

DTO – 数据传输对象与传输数据的容器完全相同。 他们没有任何行为,只有一大批二传手和得分手。 有些人使他们不可变,只是在需要时创build新的而不是更新现有的。 它们应该是可序列化的,以允许通过线路传输。

通常,DTO用于跨越进程边界将数据从一层发送到另一层,因为对远程服务的调用可能是昂贵的,因此将所有所需的数据推入DTO并以一个块(粗粒度)传送到客户端。

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

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

在前面已经提到的简单情况下,这个DTO可以用来绑定视图,但是在更复杂的情况下,需要创build一个ViewModel并将数据从DTO卸载到ViewModel,这显然是更多的工作(当应用MVVM模式时) 。

所以再次说明了DTO!= ViewModel

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

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

其次,在ASP.NET MVC中使用DTO作为ViewModel使得你的应用程序与DTO紧密结合,这正是使用DTO的相反目的。 如果你这样做,那么使用你的领域模型或DTO有什么区别,更复杂得到一个反模式?

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

相同的DTO可以具有不同的ViewModels映射,并且一个ViewModel可以由不同的DTO组成(始终不包含对象映射)。 因为我认为如果你有一个包含DTO的ViewModel会更糟,我们会遇到同样的问题。

在你的performance层中,把DTO看作是一个契约,你将会得到一个对象,你必须认为它是你的应用程序中的陌生人,并且没有任何控制权(即使你有这个服务,dto和表示层是你的)。

最后,如果你做这个干净的分离,开发人员可以轻松地一起工作。 deviseViewModels,Views和Controllers的人不必担心服务层或DTO实现,因为当其他开发人员完成他们的实现时,他将制作映射……他甚至可以使用Mocking工具或手动模拟来填充表示层用于testing数据。

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

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

如果你将使用DTO作为ViewModel,这意味着你正在DTO上高调,因为你正在改变DTO,那么它可能会影响ViewModel。

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