什么是数据传输对象?

时间:2009-06-26 20:40:24

标签: model-view-controller architecture dto data-transfer data-transfer-objects

什么是数据传输对象?

在MVC中是模型类DTO,如果没有,那么我们需要两者兼有吗?

11 个答案:

答案 0 :(得分:172)

数据传输对象是一个对象,用于封装数据,并将其从应用程序的一个子系统发送到另一个子系统。

DTO最常用于N层应用程序中的服务层,用于在自身和UI层之间传输数据。这里的主要好处是它减少了需要在分布式应用程序中通过线路发送的数据量。他们也在MVC模式中创造了很好的模型。

DTO的另一个用途是封装方法调用的参数。如果方法需要4个或5个以上的参数,这将非常有用。

使用DTO模式时,您还可以使用DTO组装器。汇编程序用于从域对象创建DTO,反之亦然。

从域对象到DTO再转回可能是一个代价高昂的过程。如果您没有创建分布式应用程序,那么您可能看不到该模式带来的任何好处,如Martin Fowler explains here

答案 1 :(得分:23)

DTO的定义可以在Martin Fowler's site找到。 DTO用于将参数传递给方法和返回类型。很多人在UI中使用它们,但是其他人会从它们中膨胀域对象。

答案 2 :(得分:18)

DTO是一个愚蠢的对象 - 它只包含属性并具有getter和setter,但没有任何其他逻辑(除了compare()或equals()实现之外)。

MVC中的模型类(假设.net MVC)通常是DTO,或DTO的集合/聚合

答案 3 :(得分:10)

一般来说,值对象应该是不可变的。与Java中的 Integer String 对象类似。我们可以使用它们在软件层之间传输数据。如果软件层或服务在不同的远程节点中运行,例如在微服务环境或旧版Java Enterprise App中运行。我们必须制作两个类的几乎完全相同的副本。这是我们遇到DTO的地方。

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

在旧版Java Enterprise Systems中,DTO可以包含各种EJB内容。

我不知道这是一个最佳实践,但我个人在我的Spring MVC / Boot项目中使用 Value Objects ,如下所示:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

控制器图层不知道实体是什么。它与表单查看值对象进行通信。表单对象具有JSR 303验证注释(例如@NotNull)和查看值对象具有用于自定义序列化的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的Paginated用户列表。然后,您可以为ORM投影创建视图值对象。

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

您可以轻松地从存储库层获取分页结果。感谢spring,你也可以只使用接口进行投影。

List<UserListItemView> find(Pageable pageable);

不要担心其他转换操作BeanUtils.copy方法正常。

答案 4 :(得分:8)

  1. 对我来说,问题 什么是DTO 的最佳答案是 DTO是不应包含任何业务逻辑的简单对象或需要测试的方法实现
  2. 通常你的模型(使用MVC模式)是智能模型,它们可以包含许多/某些方法,专门针对该模型执行一些不同的操作(不是业务逻辑,这应该在控制器上)。但是,当您传输数据(例如,从某个地方调用REST(GET / POST /无论)端点,或使用SOA等消费Web服务时...)您不希望传输数据使用端点不需要的代码的大型对象将消耗数据,并减慢传输速度。

答案 5 :(得分:5)

使用MVC数据传输对象通常用于将域模型映射到最终将由视图显示的更简单的对象。

来自Wikipedia

  

数据传输对象(DTO),以前称为值对象或VO,是   用于在软件应用程序之间传输数据的设计模式   子系统。 DTO通常与数据访问结合使用   从数据库中检索数据的对象。

答案 6 :(得分:3)

数据传输对象背后的原理是创建仅包含特定数据事务所需的必要属性的新数据对象。

好处包括:

让数据传输更安全 如果您删除所有不必要的数据,请减少传输大小。

阅读更多:https://www.codenerd.co.za/what-is-data-transfer-objects

答案 7 :(得分:1)

数据传输对象(DTO)描述“承载数据的对象 进程之间”(维基百科)或“用于封装数据的对象, 并将其从应用程序的一个子系统发送到另一个子系统”(堆栈溢出 答案)。

答案 8 :(得分:1)

所有学分都归Rick-Andreson

生产应用通常使用模型的子集来限制输入和返回的数据。这背后有多种原因,安全是一个主要原因。模型的子集通常称为数据传输对象 (DTO)、输入模型或视图模型。

DTO 可用于:

  • 防止过度发布。
  • 隐藏客户不应查看的属性。
  • 省略一些属性以减少负载大小。
  • 展平包含嵌套对象的对象图。
  • 扁平化的对象图对客户来说更方便。

DTO 方法的实际实现,由 Rick-AndresonMicrosoft Web APIs best tutorials and practices 上使用 C# 和 ASP .Net Core 5:

答案 9 :(得分:0)

DefN

DTO是硬编码数据模型。它仅解决了对由 hardcoded 生产过程处理的数据记录建模的问题,该过程中的所有字段在编译时都是已知的,因此可以通过强类型化的属性进行访问。

相反,动态模型或“属性袋”解决了在运行时创建生产过程时对数据记录建模的问题。

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是动态软件的必要组件。要实例化动态过程,一个编译器步骤是将脚本中的每台计算机绑定到脚本定义的参考属性。通过将Cvar添加到集合中来构建动态DTO。

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

竞争

注意:因为Wix将DTO的使用标记为组织参数作为“反模式”,所以我会给出权威意见。

    return View(model);  // MVC disagrees

我的协作架构取代了设计模式。请参阅我的网络文章。

参数可立即控制堆栈框架机器。如果使用连续控制,因此不需要立即控制,则模块不需要参数。我的架构没有。当参数是值类型时,机器的内部配置(方法)会增加复杂性,但也会增加值(性能)。但是,引用类型参数使使用方导致高速缓存未命中,但无论如何都会从堆中获取值-因此,只需使用引用属性配置使用方即可。机械工程的事实:对参数的依赖是一种预优化,因为加工(制造零件)本身就是浪费。有关更多信息,请参阅我的W文章。 http://www.powersemantics.com/w.html

如果福勒和公司曾经了解过任何其他架构,他们可能会意识到DTO在分布式架构之外的好处。程序员只知道分布式系统。我必须声称集成协作系统(又名生产或制造)是我自己的体系结构,因为我是第一个以这种方式编写代码的人。

有些人将DTO视为贫血领域模型,这意味着它缺乏功能,但是这假定对象必须拥有与之交互的数据。然后,此概念模型迫使您在对象之间传递数据,这是用于分布式处理的模型。但是,在生产线上,每个步骤都可以访问最终产品并对其进行更改,而无需拥有或控制它。那就是分布式处理与集成处理之间的区别。制造业将产品与运营和物流分开。

建模处理没有本质上的错误,因为一群无用的办公室工作人员在不保持电子邮件追踪的情况下互相发送电子邮件给工作,除了它在处理物流和退货问题时造成的所有额外工作和麻烦。正确建模的分布式过程会将文档(活动路由)附加到产品,以描述其来自何处以及将要进行的操作。活动路由是流程源路由的副本,该副本是在流程开始之前编写的。如果发生故障或其他紧急更改,将修改活动路由以包括将发送到的操作步骤。然后,这将解决所有投入生产的劳动力。

答案 10 :(得分:0)

我会向我的孩子解释 DTO

<块引用>

我儿子数据传输对象(又名 DTO)用于封装我们从一个应用程序(api 等)发送到另一个应用程序的数据
使用 DTO 为您的系统定义输入和输出接口

<块引用>

在这种情况下,系统是指您有多个端点(webapps、api 等),它们共同构成一个系统