什么是数据传输对象?
在MVC模型类DTO,如果不是什么区别,我们需要两者吗?
在MVC中,数据传输对象通常用于将域模型映射到最终由视图显示的更简单的对象。
从维基百科:
数据传输对象(DTO),以前称为值对象或VO 一种用于在软件应用程序之间传输数据的设计模式 子系统。dto通常与数据访问一起使用 对象从数据库中检索数据
DTO的定义可以在马丁·福勒的网站中找到。dto用于将参数传递给方法并作为返回类型。很多人在UI中使用它们,但其他人从它们扩展域对象。
DTO是一个愚蠢的对象——它只保存属性,有getter和setter,但没有其他任何重要的逻辑(除了可能是compare()或equals()实现)。
compare()
equals()
通常MVC中的模型类(假设这里是。net MVC)是dto,或者dto的集合/聚合
数据传输对象是用于封装数据并将数据从应用程序的一个子系统发送到另一个子系统的对象。
dto最常被n层应用程序中的服务层用于在自身和UI层之间传输数据。这样做的主要好处是减少了分布式应用程序中需要通过网络发送的数据量。它们还可以在MVC模式中创建很棒的模型。
dto的另一个用途是封装方法调用的参数。如果一个方法需要超过4个或5个参数,这可能很有用。
在使用DTO模式时,还可以使用DTO汇编程序。汇编程序用于从域对象创建dto,反之亦然。
从域对象转换到DTO并再转换回来可能是一个代价高昂的过程。如果你不是在创建分布式应用程序,你可能不会从马丁·福勒解释道模式中看到任何很大的好处。
一般来说,值对象应该是不可变的。像Java中的整数或字符串对象。我们可以使用它们在软件层之间传输数据。如果软件层或服务运行在不同的远程节点上,比如在微服务环境中或在遗留的Java企业应用程序中。我们必须几乎完全复制两个类。这就是我们遇到dto的地方。
|-----------| |--------------| | SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE | |-----------| |--------------|
在传统的Java企业系统中,dto可以包含各种EJB内容。
我不知道这是否是最佳实践,但我个人在我的Spring MVC/Boot项目中使用值对象,就像这样:
|------------| |------------------| |------------| -> Form | | -> Form | | -> Entity | | | Controller | | Service / Facade | | Repository | <- View | | <- View | | <- Entity / Projection View | | |------------| |------------------| |------------|
控制器层不知道实体是什么。它与形式和查看值对象通信。Form Objects有JSR 303 Validation注解(例如@ nottnull), 查看值对象有Jackson注解用于自定义序列化。(例如@JsonIgnore)
服务层通过使用实体对象与存储库层通信。实体对象上有JPA/Hibernate/Spring Data注释。每一层只与较低的层通信。由于循环依赖关系,层间通信被禁止。
User Service ----> XX CANNOT CALL XX ----> Order Service
一些ORM框架通过使用额外的接口或类具有投影的能力。因此存储库可以直接返回View对象。在那里你不需要额外的转换。
例如,这是我们的User实体:
@Entity public final class User { private String id; private String firstname; private String lastname; private String phone; private String fax; private String address; // Accessors ... }
但是你应该返回一个分页的用户列表,只包括id,名,姓。然后,您可以为ORM投影创建一个视图值对象。
public final class UserListItemView { private String id; private String firstname; private String lastname; // Accessors ... }
您可以轻松地从存储库层获得分页结果。多亏了spring,您还可以只使用接口进行投影。
List<UserListItemView> find(Pageable pageable);
不用担心其他转换操作BeanUtils.copy方法工作得很好。
BeanUtils.copy
GET
POST
数据传输对象(DTO)描述了“携带数据的对象” (维基百科)或“用于封装数据的对象”, 并将它从应用程序的一个子系统发送到另一个子系统”(堆栈溢出 回答). < / p >
DefN
DTO是一个硬编码数据模型。它只解决了建模由硬编码生产过程处理的数据记录的问题,其中所有字段在编译时都是已知的,因此通过强类型属性访问。
相反,动态模型或“属性包”解决了在运行时创建生产流程时对数据记录建模的问题。
的Cvar
DTO可以用字段或属性建模,但有人发明了一种非常有用的数据容器,称为Cvar。它是一个值的引用。当DTO用引用属性来建模时,模块可以被配置为共享堆内存,从而在堆内存上协同工作。这完全消除了代码中的参数传递和O2O通信。换句话说,具有引用属性的dto允许代码实现零耦合。
class Cvar { ... } class Cvar<T> : Cvar { public T Value { get; set; } } class MyDTO { public Cvar<int> X { get; set; } public Cvar<int> Y { get; set; } public Cvar<string> mutableString { get; set; } // >;) }
来源:http://www.powersemantics.com/
动态dto是动态软件的必要组件。要实例化动态流程,编译器的一个步骤是将脚本中的每台机器绑定到脚本定义的引用属性。动态DTO是通过将cvar添加到集合来构建的。
// a dynamic DTO class CvarRegistry : Dictionary<string, Cvar> { }
论点
注意:由于Wix将使用dto组织参数标记为“反模式”,因此我将给出权威的意见。
return View(model); // MVC disagrees
我的协作架构取代了设计模式。参考我的网络文章。
参数提供了对堆栈框架机的即时控制。如果使用连续控制,因此不需要立即控制,则模块不需要参数。我的架构没有。机器(方法)的进程内配置增加了复杂性,但当参数是值类型时,也增加了值(性能)。但是,引用类型参数会使使用者导致缓存无法从堆中获取值——因此,只需使用引用属性配置使用者即可。来自机械工程的事实:依赖参数是一种预优化,因为加工(制造部件)本身就是浪费。更多信息请参考我的W文章。http://www.powersemantics.com/w.html。
如果Fowler和他的公司了解其他架构,他们可能会意识到dto在分布式架构之外的好处。程序员只知道分布式系统。集成协作系统(又名生产又名制造)是我自己的架构,因为我是第一个用这种方式写代码的人。
有些人认为DTO是一个缺乏功能的域模型,但这假设对象必须拥有与其交互的数据。然后,这个概念模型迫使您在对象之间传递数据,这是用于分布式处理的模型。然而,在生产线上,每个步骤都可以访问最终产品并在不拥有或控制它的情况下对其进行更改。这就是分布式处理和集成处理之间的区别。生产将产品与运营和物流分开。
将处理建模为一群无用的办公室工作人员相互发送电子邮件而不保留电子邮件跟踪,这本身并没有什么错,除了它在处理物流和退货问题方面产生的所有额外工作和头痛。正确建模的分布式流程将文档(活动路由)附加到产品,描述它来自哪些操作以及将执行哪些操作。活动路由是流程源路由的副本,在流程开始之前写入。在出现缺陷或其他紧急更改时,将修改活动路由以包括将发送到的操作步骤。这就包括了所有投入生产的劳动。
数据传输对象背后的原理是创建新的数据对象,其中只包括特定数据事务所需的必要属性。
福利包括:
让数据传输更安全
阅读更多:https://www.codenerd.co.za/what-is-data-transfer-objects
我会把DTO解释给我的孩子
我的儿子,数据传输对象(又名DTO) **用于封装我们从一个端点发送到另一个端点的数据。 使用DTO为系统中的端点定义输入和输出接口 在这种情况下,可以将系统看作端点的集合。端点可以是任何相互通信的东西(移动应用程序,web应用程序,后端API)。
在这种情况下,可以将系统看作端点的集合。端点可以是任何相互通信的东西(移动应用程序,web应用程序,后端API)。
所有学分归Rick-Andreson
生产应用程序通常限制使用模型子集输入和返回的数据。这背后有很多原因,安全是一个主要原因。模型的子集通常被称为数据传输对象 (DTO),输入模型或视图模型。
DTO可用于:
DTO方法的实际实现,通过Rick-Andreson在微软Web api最佳教程和实践上使用c#和asp.net Core 5:
一些程序员使用DTO来区分将通过API传递的最终对象数据。它基本上是端点的有效载荷对象。比如,你可以将你传递给服务器的联系人表单值对象命名为contactFormDto or contactFromPayload,然后你或任何其他程序员都知道你在该对象中拥有的是数据的最终形状,它将通过网络传播。
contactFormDto or contactFromPayload