视图模型和数据传输对象有什么区别?
我的这个问题基于 Fowler PoEAA。鉴于您对本文的熟悉程度,ASP.NET MVC 中使用的 ViewModel 是否与 DTO 相同?为什么或为什么不呢?谢谢。
I'm basing this question on Fowler PoEAA. Given your familiarity with this text, aren't the ViewModels used in ASP.NET MVC the same as DTOs? Why or why not? Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它们具有类似的目的(为应用程序的另一层封装数据),但它们的做法不同并且出于不同的原因。
DTO 的目的是减少应用程序各层之间的调用次数,特别是当这些调用成本高昂时(例如分布式系统)。 DTO 几乎总是可序列化的,并且几乎从不包含任何行为。
例如,您正在开发一个电子商务网站。
CreateCustomer
和AddCustomerAddress
是数据库级别的单独操作,但出于性能原因,您可能希望将其数据聚合到NewCustomerWithAddressDto
中,以便您的客户端只需要与服务器进行一次往返,并且不需要关心服务器可能正在对数据包执行一堆不同的操作。术语“ViewModel”在不同风格的 MV* 中含义略有不同,但其目的主要是关注点分离。您的模型经常为了演示之外的某些目的进行优化,并且 ViewModel 的责任是将您的视图与模型的实现细节分离。此外,大多数 MV* 模式建议让您的视图尽可能“哑”,因此 ViewModel 有时会负责表示逻辑。
例如,在同一个电子商务应用程序中,您的
CustomerModel
是在“新客户”视图上呈现的错误“形状”。对于初学者来说,您的视图有两个表单字段供用户输入和确认其密码,而您的CustomerModel
根本不包含密码字段!您的 NewCustomerViewModel 将包含这些字段,并且可能根据您的 MV* 风格负责一些表示逻辑(例如显示/隐藏视图的某些部分)和基本验证(例如确保密码字段匹配)。They serve a similar purpose (encapsulating data for another layer of the application) but they do it differently and for different reasons.
The purpose of a DTO is to reduce the number of calls between tiers of an application, especially when those calls are expensive (e.g. distributed systems). DTOs are almost always trivially serializable, and almost never contain any behaviour.
For example, you're developing an e-Commerce site.
CreateCustomer
andAddCustomerAddress
are separate operations at the database level, but you might for performance reasons want to aggregate their data into aNewCustomerWithAddressDto
so that your client only needs to make one round-trip to the server, and doesn't need to care that the server might be doing a bunch of different things with the parcel of data.The term "ViewModel" means slightly different things in different flavours of MV*, but its purpose is mainly separation of concerns. Your Model is frequently optimised for some purpose other than presentation, and it's the responsibility of the ViewModel to decouple your View from the Model's implementation details. Additionally, most MV* patterns advise making your Views as "dumb" as possible, and so the ViewModel sometimes takes responsibility for presentation logic.
For example, in the same e-Commerce application, your
CustomerModel
is the wrong "shape" for presentation on your "New Customer" View. For starters, your View has two form fields for your user to enter and confirm their password, and yourCustomerModel
doesn't contain a password field at all! YourNewCustomerViewModel
will contain those fields and might, depending on your flavour of MV*, be responsible for some presentation logic (e.g. to show/hide parts of the view) and basic validation (e.g. ensuring that both password fields match).目的不同:
因此,通常 ViewModel 包含表示数据,在很多情况下与 DTO 中的数据类似,但也有一些差异。想想枚举、本地化、货币、日期格式等的表示。这是因为通常在你看来不应该有逻辑。
The purpose is different:
So normally ViewModels contain the presentation data, witch is in a lot of cases similar to what is in a DTO, but with some differences. Think of representation of enums, localization, currency, date formats, ... . This is because normally there should be no logic in your view.
MVVM 和 MVP 中的 DTO 通常是非常愚蠢的对象,基本上只是一堆属性 setter 和 getter。另一方面,ViewModel 可以有一些行为。
使用 DTO 的一个实际积极的副作用是允许更轻松的序列化。如果您有一个相当复杂的对象(例如 C#),您经常会发现自己必须有选择地关闭不想序列化的对象。这可能会变得相当难看,DTO 简化了这个过程。
DTOs in MVVM and MVP are usually Very Dumb Objects and are basically just a bunch of property setters and getters. ViewModels on the other hand can have some behaviour.
A practical positive side effect of having DTOs is allow easier serialization. If you have a rather complex object in, say C#, you will often find yourself having to selectively turn things off that you don't want serialized. This can get rather ugly and DTOs simplify this process.
视图模型和数据传输对象有相似之处和差异。
相似的:
将记录(对象实例,可能是序列化的)中的数据传输到接收器,无论是视图还是服务
差异:
视图模型旨在发送到视图,并在视图中显示它的格式。
视图模型还将数据发送回控制器。
DTO 通常不用于演示。它的目的是发送原始数据。
A View Model and a Data Transfer object has similarities and differences.
Similar:
Transfer data in a record (object instance, perhaps serialized) to a receiver, whether a view or a service
Difference:
A View Model is intended to be sent to a View, where it will be displayed, with formatting.
A View Model also sends back data to a controller.
A DTO is usually not intended for presentation. It is intended to send raw data.
两者都有相同的目的:对传入和传出后端的数据进行建模。
视图模型模型数据从前端视觉系统(表单、用户输入等)到达后端,反之亦然,模型数据出于相同目的发送到前端以满足某些视觉要求。
数据传输对象对从某些客户端系统(后台 API、仍需要处理的数据、客户端后台服务等)到达后端的数据进行建模,反之亦然对要发送到客户端系统的数据进行建模。即使客户端系统可能具有可视元素,DTO 调用本身也用于非可视用例。
两者之间的技术差异源于上述两者的语义和上下文含义,例如视图模型可能具有更多行为。
Both serve the same purpose to model data coming to and from the backend.
View Models model data hitting the backend from a front end visual system (forms, user inputs, etc) and vice versa model data to be sent to the front end for the same purpose to fulfill some visual requirement.
Data Transfer Objects model data hitting the backend from some client system (background api's, data that still needs to be worked on, a clients background services, etc) and vice versa model data to be sent to the client system. Even though the client system may have visual elements, the DTO call itself is used for a non visual use case.
The technical differences between the two arise from the semantic and contextual meaning of the two as mentioned above, such as view models possibly having more behaviour.
我一直认为 DTO 应该就像您的实体一样,而 ViewModel 在呈现给视图时是这些 DTO 的容器。
在这种情况下,您将创建“伪”DTO,将 2 个或多个其他 DTO 组合在一起,以将一个“模型”中的数据传递给方法或 API 等。
不过,我从未为这些“伪”DTO 制定命名约定,因此最终只是在它们后缀为“DTO”,但将它们与视图模型一起放入模型文件夹中
I always thought DTO's were supposed to be almost like for like your Entities and ViewModels were containers for those DTO's when presenting to the View.
In that instance you would create 'pseudo' DTO's that combine 2 or more other DTO's together to pass data in one 'model' to a method or API etc.
I never came up with a naming convention for those 'pseudo' DTO's though, so just ended up suffixing them with "DTO", but put them in the models Folder along with the view models ????♂️
The ViewModel may have presentation logic based on; the current user's permissions, the display type, the data in the DTO's etc.
I've always tried to keep my views as 'dumb' as possible with as little as possible code in them, and just bound the view to the properties in the view model.