我正在使用NHibernate持久化域对象。为简单起见,我将ASP.NET MVC项目用作表示层和服务层。
我想从控制器类中以XML返回我的域对象。在阅读了一些有关Stack Overflow的文章之后,我收集了DTO。但是,我也遇到过有关ViewModel的帖子。
我的问题:数据传输对象和ViewModel是同一件事吗?还是ViewModel是DTO的一种子模式?
我正在使用NHibernate持久化域对象。为简单起见,我将ASP.NET MVC项目用作表示层和服务层。
我想从控制器类中以XML返回我的域对象。在阅读了一些有关Stack Overflow的文章之后,我收集了DTO。但是,我也遇到过有关ViewModel的帖子。
我的问题:数据传输对象和ViewModel是同一件事吗?还是ViewModel是DTO的一种子模式?
Answers:
DTO的规范定义是没有任何行为的对象的数据形状。
ViewModels是视图的模型。ViewModel通常是来自一个或多个对象(或DTO)以及特定于视图行为的任何其他成员(可由视图执行的方法,指示如何切换视图元素的属性等)的全部或部分数据。您可以将viewmodel视为视图的所有数据以及行为。ViewModel可能会也可能不会一对一映射到业务对象或DTO。
顺便说一句,如果某个视图模型需要来自持久对象的数据子集,则NHibernate 投影会派上用场。
ASP.NET MVC实践中的ViewModel与DTO相同,但是MVVM模式中的ViewModel与DTO不同,因为MVVM中的ViewModel具有行为,但DTO没有。
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在生活中有不同的用途
首先,主要区别在于ViewModel可以具有DTO一定不能禁止的行为或方法!
其次,在ASP.NET MVC中将DTO用作ViewModel可以使您的应用程序与DTO紧密耦合,这与使用DTO恰恰相反。如果这样做,则使用域模型或DTO有什么区别,获得反模式的复杂性如何?
ASP.NET中的ViewModel也可以使用DataAnnotations进行验证。
相同的DTO可以具有不同的ViewModels映射,并且一个ViewModel可以由不同的DTO组成(总是具有对象映射而不是合成)。因为我认为如果您的ViewModel包含DTO甚至更糟,我们将遇到同样的问题。
在您的表示层中,将DTO视为合同,您将收到一个对象,您必须将其视为您的应用程序的陌生对象,并且对其没有任何控制权(即使您拥有服务,dto和表示层)是你的)。
最后,如果您进行这种干净的分离,显影剂可以轻松地协同工作。设计ViewModel,View和Controller的人不必担心服务层或DTO实现,因为他将在其他开发人员完成其实现时进行映射...他甚至可以使用Mocking工具或手动模拟来填充表示层包含要测试的数据。
如果将DTO用作ViewModel,则意味着由于某些原因要更改DTO,因此您对DTO的依赖性很高,那么这可能会影响ViewModel。
更好地使用DTO并转换为viewmodel。
DTO当我们需要在单个视图中显示/使用多个模型数据/属性时,我们可以使用与Model类相同的模型,也可以使用viewmodel。示例:我首先使用实体框架数据库创建一些模型。因此,现在所有模型都基于数据库生成。现在我们需要数据注释,对于这些数据注释,我们可以创建一个文件夹名称DTO。在此DTO文件夹中,我们可以使所有已经生成的模型保持准确,并在属性上方添加数据注释。然后,我们可以使用此DTO类使用任何操作(使用controller,views)。当我们需要复杂的视图时,我的意思是当我们在一个视图中需要多个类数据时,可以使用viewmodel。对于viewmodel,我们可以创建一个文件夹名称viewmodel,然后创建一个自定义类并保留我们需要的属性。我试图清除自己。任何建议高度赞赏。