什么是数据传输对象 (DTO)?

发布于 2024-07-26 00:23:28 字数 41 浏览 11 评论 0原文

在MVC中模型类是DTO吗? 如果不是,有什么区别,我们都需要吗?

In MVC are the model classes DTO? If not, what are the differences and do we need both?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

む无字情书 2024-08-02 00:23:28

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

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

DTO 的另一个用途是封装方法调用的参数。 如果方法采用四个或五个以上参数,这可能很有用。

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

从域对象到 DTO 的转换以及再次转换可能是一个成本高昂的过程。 如果您不创建分布式应用程序,您可能不会从该模式中看到任何巨大的好处,正如Martin福勒在此解释

A Data Transfer Object is an object that is used to encapsulate data, and send it from one subsystem of an application to another.

DTOs are most commonly used by the Services layer in an N-Tier application to transfer data between itself and the UI layer. The main benefit here is that it reduces the amount of data that needs to be sent across the wire in distributed applications. They also make great models in the MVC pattern.

Another use for DTOs can be to encapsulate parameters for method calls. This can be useful if a method takes more than four or five parameters.

When using the DTO pattern, you would also make use of DTO assemblers. The assemblers are used to create DTOs from Domain Objects, and vice versa.

The conversion from Domain Object to DTO and back again can be a costly process. If you're not creating a distributed application, you probably won't see any great benefits from the pattern, as Martin Fowler explains here.

翻身的咸鱼 2024-08-02 00:23:28

DTO 的定义可以在 Martin Fowler 的网站 上找到。 DTO 用于将参数传输到方法并作为返回类型。 很多人在 UI 中使用它们,但其他人则从它们中扩充域对象。

The definition for DTO can be found on Martin Fowler's site. DTOs are used to transfer parameters to methods and as return types. A lot of people use those in the UI, but others inflate domain objects from them.

猫烠⑼条掵仅有一顆心 2024-08-02 00:23:28

DTO 是一个哑对象 - 它只保存属性并具有 getter 和 setter,但没有其他任何重要的逻辑(除了 compare()equals()执行)。

MVC 中的典型模型类(假设此处为 .net MVC)是 DTO,或 DTO 的集合/聚合

A DTO is a dumb object - it just holds properties and has getters and setters, but no other logic of any significance (other than maybe a compare() or equals() implementation).

Typically model classes in MVC (assuming .net MVC here) are DTOs, or collections/aggregates of DTOs

节枝 2024-08-02 00:23:28

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

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

在遗留的 Java Enterprise Systems DTO 中可以包含各种 EJB 内容。

我不知道这是否是最佳实践,但我个人在 Spring MVC/Boot 项目中使用值对象,如下所示:

        |------------|         |------------------|                             |------------|
-> 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对象。 在那里你不需要额外的转换。

例如,这是我们的 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、firstname、lastname。 然后您可以创建一个用于 ORM 投影的视图值对象。

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

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

List<UserListItemView> find(Pageable pageable);

不用担心其他转换操作 BeanUtils.copy 方法工作得很好。

In general Value Objects should be Immutable. Like Integer or String objects in Java. We can use them for transferring data between software layers. If the software layers or services running in different remote nodes like in a microservices environment or in a legacy Java Enterprise App. We must make almost exact copies of two classes. This is the where we met DTOs.

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

In legacy Java Enterprise Systems DTOs can have various EJB stuff in it.

I do not know this is a best practice or not but I personally use Value Objects in my Spring MVC/Boot Projects like this:

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

Controller layer doesn't know what are the entities are. It communicates with Form and View Value Objects. Form Objects has JSR 303 Validation annotations (for instance @NotNull) and View Value Objects have Jackson Annotations for custom serialization. (for instance @JsonIgnore)

Service layer communicates with repository layer via using Entity Objects. Entity objects have JPA/Hibernate/Spring Data annotations on it. Every layer communicates with only the lower layer. The inter-layer communication is prohibited because of circular/cyclic dependency.

User Service ----> XX CANNOT CALL XX ----> Order Service

Some ORM Frameworks have the ability of projection via using additional interfaces or classes. So repositories can return View objects directly. There for you do not need an additional transformation.

For instance this is our User entity:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

But you should return a Paginated list of users that just include id, firstname, lastname. Then you can create a View Value Object for ORM projection.

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

You can easily get the paginated result from repository layer. Thanks to spring you can also use just interfaces for projections.

List<UserListItemView> find(Pageable pageable);

Don't worry for other conversion operations BeanUtils.copy method works just fine.

白云不回头 2024-08-02 00:23:28
  1. 对我来说,什么是 DTO 问题的最佳答案是 DTO 是简单的对象,不应包含任何需要测试的业务逻辑或方法实现< /em>.
  2. 通常,您的模型(使用 MVC 模式)是智能模型,它们可以包含许多/一些方法,专门为该模型执行一些不同的操作(不是业务逻辑,这应该在控制器上)。 但是,当您传输数据(例如,从某处调用 REST(GET/POST/其他)端点,或使用 SOA 消费 Web 服务等...)时,您不想使用端点不需要的代码传输大尺寸对象,这会消耗数据并减慢传输速度。
  1. To me the best answer to the question what is a DTO is that DTO's are simple objects that should not contain any business logic or methods implementation that would require testing.
  2. Normally your model (using the MVC pattern) are intelligent models, and they can contain a lot of/some methods that do some different operations for that model specifically (not business logic, this should be at the controllers). However, when you transfer data (eg. calling a REST (GET/POST/whatever) endpoint from somewhere, or consuming a webservice using SOA, etc...) you do not want to transmit the big sized object with code that is not necessary for the endpoint, will consume data, and slow down the transfer.
夢归不見 2024-08-02 00:23:28

所有功劳均归于 Rick-Andreson

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

DTO 可用于 PHOFF

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

DTO 方法的实际实现,由 Rick-AndresonMicrosoft Web API使用 C# 和 ASP .Net Core 5 的最佳教程和实践

All credits goes to Rick-Andreson

Production apps typically limit the data that's input and returned using a subset of the model. There are multiple reasons behind this and security is a major one. The subset of a model is usually referred to as a Data Transfer Object (DTO), input model, or view model.

A DTO may be used to P.H.O.F.F:

  • Prevent over-posting.
  • Hide properties that clients are not supposed to view.
  • Omit some properties in order to reduce payload size.
  • Flatten object graphs that contain nested objects.
  • Flattened object graphs can be more convenient for clients.

Practical implementation of a DTO approach, by Rick-Andreson on Microsoft Web APIs best tutorials and practices using C# and ASP .Net Core 5:

栀子花开つ 2024-08-02 00:23:28

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

来自维基百科

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

With MVC data transfer objects are often used to map domain models to simpler objects that will ultimately get displayed by the view.

From Wikipedia:

Data transfer object (DTO), formerly known as value objects or VO, is
a design pattern used to transfer data between software application
subsystems. DTOs are often used in conjunction with data access
objects to retrieve data from a database.

绳情 2024-08-02 00:23:28

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

好处包括:

使数据传输更加安全
如果删除所有不必要的数据,则可以减少传输大小。

了解更多:https://www.codenerd.co.za/what-是数据传输对象

The principle behind Data Transfer Object is to create new Data Objects that only include the necessary properties you need for a specific data transaction.

Benefits include:

Make data transfer more secure
Reduce transfer size if you remove all unnecessary data.

Read More: https://www.codenerd.co.za/what-is-data-transfer-objects

冬天旳寂寞 2024-08-02 00:23:28

一些程序员使用 DTO 来区分将通过 API 传递的最终对象数据。 因此,它基本上是端点的有效负载对象。 例如,您可以将传递给服务器的联系表单值对象命名为 contactFormDto 或 contactFromPayload,然后您或任何其他程序员知道该对象中的内容是数据的最终形状,即打算通过网络去旅行。

Some programmers use DTO to distinguish their final object data that is going to be passed through an API. So, it is basically a payload object to an endpoint. Like, you could name your contact form values object that you pass to the server as contactFormDto or contactFromPayload, then you or any other programmer know what you have in that object is final shape of the data, that is going to travel through network.

苦行僧 2024-08-02 00:23:28

我会向我的孩子解释 DTO

我的儿子,数据传输对象(又名 DTO)** 用于封装我们从一个端点发送到另一个端点的数据。
使用 DTO 定义系统中端点的输入和输出接口

<块引用>

在这种情况下,将系统视为端点的集合。 端点可以是相互通信的任何内容(移动应用程序、Web 应用程序、后端 API)。

I would explain DTO to my kid as

My son, Data Transfer Object (aka DTO) **is used to encapsulate data we send from one endpoint to another.
Use DTO to define interfaces for input and output for endpoints in your system

In this context think of a system as a collection of endpoints. And endpoints can be anything between (mobile app, web app, backend API) that talk with each other.

冷弦 2024-08-02 00:23:28

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

Data transfer object (DTO) describes “an object that carries data
between processes” (Wikipedia) or an “object that is used to encapsulate data,
and send it from one subsystem of an application to another” (Stack Overflow
answer).

独夜无伴 2024-08-02 00:23:28

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 是动态软件的必要组件。 要实例化动态进程,一个编译器步骤是将脚本中的每台机器绑定到脚本定义的引用属性。 通过将 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 是一种贫乏的领域模型,这意味着它缺乏功能,但这假设对象必须拥有与其交互的数据。 然后,这个概念模型迫使您在对象之间传递数据,这就是分布式处理的模型。 然而,在生产线上,每个步骤都可以访问最终产品并对其进行更改,而无需拥有或控制它。 这就是分布式处理和集成处理之间的区别。 制造将产品与运营和物流分开。

将处理建模为一群无用的办公室工作人员,他们通过电子邮件相互发送工作而不保留电子邮件跟踪,这本身并没有什么问题,除了在处理物流和退货问题时产生的所有额外工作和头痛之外。 正确建模的分布式流程会将一个文档(主动路由)附加到产品中,描述它来自和将进行的操作。 活动路由是流程源路由的副本,在流程开始之前写入。 如果出现缺陷或其他紧急变化,活动路由将被修改以包括它将被发送到的操作步骤。 这就说明了投入生产的所有劳动力。

DefN

A DTO is a hardcoded data model. It only solves the problem of modeling a data record handled by a hardcoded production process, where all fields are known at compile-time and therefore accessed via strongly typed properties.

In contrast, a dynamic model or "property bag" solves the problem of modeling a data record when the production process is created at runtime.

The Cvar

A DTO can be modeled with fields or properties, but someone invented a very useful data container called the Cvar. It is a reference to a value. When a DTO is modeled with what I call reference properties, modules can be configured to share heap memory and thereby collaboratively work on it. This completely eliminates parameter passing and O2O communication from your code. In other words, DTOs having reference properties allow code to achieve zero coupling.

    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; } // >;)
    }

Source: http://www.powersemantics.com/

Dynamic DTOs are a necessary component for dynamic software. To instantiate a dynamic process, one compiler step is to bind each machine in the script to the reference properties the script defines. A dynamic DTO is built by adding the Cvars to a collection.

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

Contentions

Note: because Wix labeled the use of DTOs for organizing parameters as an "anti-pattern", I will give an authoritative opinion.

    return View(model);  // MVC disagrees

My collaborative architecture replaces design patterns. Refer to my web articles.

Parameters provide immediate control of a stack frame machine. If you use continuous control and therefore do not need immediate control, your modules do not need parameters. My architecture has none. In-process configuration of machines (methods) adds complexity but also value (performance) when the parameters are value types. However, reference type parameters make the consumer cause cache misses to get the values off the heap anyway -- therefore, just configure the consumer with reference properties. Fact from mechanical engineering: reliance on parameters is a kind of preoptimization, because processing (making components) itself is waste. Refer to my W article for more information. http://www.powersemantics.com/w.html.

Fowler and company might realize the benefits of DTOs outside of distributed architecture if they had ever known any other architecture. Programmers only know distributed systems. Integrated collaborative systems (aka production aka manufacturing) are something I had to claim as my own architecture, because I am the first to write code this way.

Some consider the DTO an anemic domain model, meaning it lacks functionality, but this assumes an object must own the data it interacts with. This conceptual model then forces you to deliver the data between objects, which is the model for distributed processing. However on a manufacturing line, each step can access the end product and change it without owning or controlling it. That's the difference between distributed and integrated processing. Manufacturing separates the product from operations and logistics.

There's nothing inherently wrong with modeling processing as a bunch of useless office workers who e-mail work to one another without keeping an e-mail trail, except for all the extra work and headache it creates in handling logistics and return problems. A properly modeled distributed process attaches a document (active routing) to the product describing what operations it came from and will go to. The active routing is a copy of the process source routing, which is written before the process begins. In the event of a defect or other emergency change, the active routing is modified to include the operation steps it will be sent to. This then accounts for all the labor which went into production.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文