什么是数据传输对象?
在MVC中,模型类是DTO,如果不是,则有什么区别,我们是否需要两者?
什么是数据传输对象?
在MVC中,模型类是DTO,如果不是,则有什么区别,我们是否需要两者?
Answers:
数据传输对象是用于封装数据并将其从应用程序的一个子系统发送到另一个子系统的对象。
NTO应用程序中的服务层最常使用DTO在自身和UI层之间传输数据。这样做的主要好处是,它减少了分布式应用程序中需要通过网络发送的数据量。他们还在MVC模式中建立了出色的模型。
DTO的另一个用途是封装方法调用的参数。如果某个方法采用的参数超过4个或5个,则这将很有用。
使用DTO模式时,您还将使用DTO汇编程序。汇编程序用于从域对象创建DTO,反之亦然。
从域对象到DTO的转换再转换回来可能是一个昂贵的过程。如果您不创建分布式应用程序,那么该模式可能不会带来任何好处,正如Martin Fowler在此处解释的那样
DTO的定义可以在Martin Fowler的站点上找到。DTO用于将参数传递给方法并作为返回类型。很多人在UI中使用它们,但其他人则从其中膨胀域对象。
DTO是一个愚蠢的对象-它仅保留属性并具有getter和setter,但没有其他任何有意义的逻辑(可能是compare()或equals()实现)。
通常,MVC中的模型类(此处为.net MVC)是DTO或DTO的集合/集合。
通常,值对象应该是不可变的。就像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 | |
|------------| |------------------| |------------|
控制器层不知道实体是什么。它与Form和View Value Objects通信。表单对象具有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的用户分页列表。然后,您可以为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
无论如何)终结点,或使用SOA使用网络服务等)时,您不希望使用不需要执行以下代码的大型对象来传输数据端点将消耗数据,并减慢传输速度。数据传输对象(DTO)描述“在进程之间携带数据的对象”(维基百科)或“用于封装数据并将其从应用程序的一个子系统发送到另一个子系统的对象”(堆栈溢出答案)。
国防部
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在分布式架构之外的好处。程序员只知道分布式系统。集成协作系统(又名生产aka制造)是我必须声明的自己的体系结构,因为我是第一个以这种方式编写代码的人。
有些人将DTO视为贫血领域模型,这意味着DTO缺乏功能,但是这假定对象必须拥有与之交互的数据。然后,此概念模型迫使您在对象之间传递数据,这是用于分布式处理的模型。但是,在生产线上,每个步骤都可以访问最终产品并对其进行更改,而无需拥有或控制它。那就是分布式处理与集成处理之间的区别。制造业将产品与运营和物流分开。
作为一群无用的上班族,他们在不保持电子邮件追踪的情况下通过电子邮件相互发送电子邮件的过程没有建模方面的内在错误,除了它在处理物流和退货问题时造成的所有额外工作和麻烦。正确建模的分布式过程会将文档(活动路由)附加到产品上,以描述产品来自何处以及将要进行的操作。活动路由是流程源路由的副本,该副本是在流程开始之前编写的。如果发生故障或其他紧急更改,则修改活动路由以包括将发送到的操作步骤。这样就解决了所有投入生产的劳动。