【发布时间】:2010-11-06 06:37:16
【问题描述】:
什么是数据传输对象?
在 MVC 中是模型类 DTO,如果不是,有什么区别?我们需要两者吗?
【问题讨论】:
标签: model-view-controller architecture dto data-transfer data-transfer-objects
什么是数据传输对象?
在 MVC 中是模型类 DTO,如果不是,有什么区别?我们需要两者吗?
【问题讨论】:
标签: model-view-controller architecture dto data-transfer data-transfer-objects
DTO 的定义可以在Martin Fowler's site 上找到。 DTO 用于将参数传递给方法并作为返回类型。很多人在 UI 中使用它们,但其他人从它们中扩充域对象。
【讨论】:
DTO 是一个愚蠢的对象 - 它只包含属性并具有 getter 和 setter,但没有其他任何重要的逻辑(可能是 compare() 或 equals() 实现)。
MVC 中的典型模型类(假设此处为 .net MVC)是 DTO,或 DTO 的集合/聚合
【讨论】:
数据传输对象是用于封装数据并将其从应用程序的一个子系统发送到另一个子系统的对象。
N 层应用程序中的服务层最常使用 DTO 在其自身和 UI 层之间传输数据。这里的主要好处是它减少了分布式应用程序中需要通过网络发送的数据量。他们还在 MVC 模式中制作了出色的模型。
DTO 的另一个用途是封装方法调用的参数。如果一个方法需要四个或五个以上的参数,这会很有用。
当使用 DTO 模式时,您还可以使用 DTO 汇编器。汇编器用于从域对象创建 DTO,反之亦然。
从域对象到 DTO 再转换回来可能是一个代价高昂的过程。如果您不创建分布式应用程序,您可能不会从该模式中看到任何巨大的好处,例如 Martin Fowler explains here。
【讨论】:
一般值对象应该是不可变的。像 Java 中的 Integer 或 String 对象。我们可以使用它们在软件层之间传输数据。如果软件层或服务在不同的远程节点中运行,例如在微服务环境或旧版 Java 企业应用程序中。我们必须几乎完全复制两个类。这就是我们遇到 DTO 的地方。
|-----------| |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------| |--------------|
在旧版 Java 企业系统中,DTO 可以包含各种 EJB 内容。
我不知道这是否是最佳实践,但我个人在我的 Spring MVC/Boot 项目中使用 Value Objects,如下所示:
|------------| |------------------| |------------|
-> Form | | -> Form | | -> Entity | |
| Controller | | Service / Facade | | Repository |
<- View | | <- View | | <- Entity / Projection View | |
|------------| |------------------| |------------|
Controller 层不知道实体是什么。它与 Form 和 View Value Objects 通信。表单对象具有 JSR 303 验证注释(例如 @NotNull),View Value Objects 具有用于自定义序列化的 Jackson 注释。 (例如@JsonIgnore)
服务层通过使用实体对象与存储库层进行通信。实体对象上有 JPA/Hibernate/Spring Data 注释。每层仅与较低层通信。由于循环/循环依赖,层间通信被禁止。
User Service ----> XX CANNOT CALL XX ----> Order Service
一些 ORM 框架具有通过使用额外的接口或类进行投影的能力。因此存储库可以直接返回 View 对象。在那里你不需要额外的转换。
例如这是我们的用户实体:
@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、firstname、lastname 的用户分页列表。然后你可以为 ORM 投影创建一个 View Value Object。
public final class UserListItemView {
private String id;
private String firstname;
private String lastname;
// Accessors ...
}
您可以轻松地从存储库层获取分页结果。感谢 spring,您还可以只使用接口进行投影。
List<UserListItemView> find(Pageable pageable);
不用担心其他转换操作BeanUtils.copy 方法工作正常。
【讨论】:
GET/POST/whatever) 端点,或使用 SOA 使用 Web 服务等...)您不想使用端点不需要的代码会消耗数据并减慢传输速度。【讨论】:
数据传输对象(DTO)描述了“一个携带数据的对象 进程之间”(维基百科)或“用于封装数据的对象, 并将其从应用程序的一个子系统发送到另一个”(堆栈溢出 回答)。
【讨论】:
DefN
DTO 是一个硬编码数据模型。它只解决了对由硬编码生产过程处理的数据记录进行建模的问题,其中所有字段在编译时都是已知的,因此可以通过强类型属性访问。
相比之下,动态模型或“属性包”解决了在运行时创建生产过程时对数据记录进行建模的问题。
Cvar
可以使用字段或属性对 DTO 进行建模,但有人发明了一种非常有用的数据容器,称为 Cvar。它是对值的引用。当 DTO 使用我称之为 reference properties 的东西建模时,可以将模块配置为共享堆内存,从而协作处理它。这完全消除了代码中的参数传递和 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 是动态软件的必要组件。为了实例化一个动态过程,一个编译器步骤是将脚本中的每台机器绑定到脚本定义的引用属性。通过将 Cvar 添加到集合中来构建动态 DTO。
// 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)用于封装我们从一个应用程序(api 等)发送到另一个应用程序的数据
使用 DTO 为您的系统定义输入和输出接口这里所说的系统是指您有多个端点(webapps、api 等),它们共同构成一个系统
【讨论】:
所有学分都归Rick-Andreson
生产应用程序通常会限制使用模型子集输入和返回的数据。这背后有多种原因,安全性是一个主要原因。模型的子集通常称为数据传输对象 (DTO)、输入模型或视图模型。
DTO 可用于:
DTO 方法的实际实现,Rick-Andreson 在 Microsoft Web APIs best tutorials and practices 上使用 C# 和 ASP .Net Core 5:
【讨论】:
一些程序员使用 DTO 来区分将通过 API 传递的最终对象数据。因此,它基本上是端点的有效负载对象。例如,您可以将传递给服务器的联系表单值对象命名为contactFormDto or contactFromPayload,然后您或任何其他程序员都知道您在该对象中拥有的是数据的最终形状,它将通过网络传播。
【讨论】: