什么是数据传输对象?

问题描述 投票:165回答:6

什么是数据传输对象?

在MVC中是模型类DTO,如果没有,有什么不同,我们是否需要两者?

model-view-controller architecture dto data-transfer data-transfer-objects
6个回答
181
投票

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

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

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

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

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


24
投票

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


19
投票

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

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


10
投票

通常,Value Objects应该是Immutable。与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方法工作正常。


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

5
投票

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

来自Wikipedia

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

© www.soinside.com 2019 - 2024. All rights reserved.