我有术语问题。受到Fowler的影响,DTO是“在进程之间传输数据以减少方法调用次数的对象。” (http://martinfowler.com/eaaCatalog/dataTransferObject.html)。据我所知,减少方法调用的唯一方法是将它们联合起来。所以DTO是复合对象,包含一些实体。
例如,我们有两个简单的实体CoinInfo和ProductInfo:
public class CoinInfo
{
public int CoinId { get; set; }
public int Denomination { get; set; }
public int Quantity { get; set; }
}
public class ProductInfo
{
public int ProductId { get; set; }
public ProductTypes ProductType { get; set; }
public int Price { get; set; }
public int Count { get; set; }
}
我们还有复杂的对象SomeDto,将CoinInfo和ProductInfo结合在一起。
public class SomeComplex
{
public List<CoinInfo> UserWallet { get; set; }
public List<ProductInfo> Products { get; set;}
}
那么,ProductInfo和CoinInfo也是“DTO”还是“实体”?
答案 0 :(得分:3)
数据传输对象在跨越类,组件或应用程序边界时起作用。您使用DTO来减少类,组件或应用程序之间的耦合。
例如,在构建客户端要使用的服务时,您可能需要引入三个组件:
现在,您希望与该服务通信的客户端应用程序只需引用客户端库和DTO库。
,您的服务用于实现其魔力的其他类型对客户来说根本不感兴趣。现在,DTO的重点在于您使用它们来建模您的API。您可以决定从服务中公开的内容以及此数据的外观。您可以选择合成,将较小的DTO聚合为较大的DTO,如图所示。
您必须牢记的是不通过DTO公开服务内部。您正在使用单词&#34; entities&#34;,这让我觉得您正在尝试公开,例如,在DTO中汇总的实体框架模型。你不应该这样做。这样做是为了创建一个泄漏的抽象&#34;,使得更改数据库(添加或删除列,替换ORM,......)变得更加困难,并且更改服务返回的信息(添加或删除属性,...)。除此之外,使用实体框架模型作为DTO引入了质量赋值,延迟加载和循环引用的问题,所有这些都需要解决方法。
您可以使用属性解决这些潜在问题,让您的ORM或服务序列化程序忽略这些无关的属性,但这些仍然是解决方法。如果你真的需要公开看起来很像你的数据模型的DTO,那么引入映射(例如使用AutoMapper):
在这种情况下,您服务的数据层和从您的服务返回的模型会被解耦。
如果所有这些都不是您所关注的,而只是命名法:是的,您展示的所有三个课程都是DTO。
答案 1 :(得分:2)
由于CoinInfo
和ProductInfo
也适合执行 CRUD (即创建,读取,更新,删除)操作,我会说关联根和它自己的关联也是DTO。
当您询问这些类是否为实体时,它取决于您理解为 entity 的内容。如果你想知道它们是否是域对象,除非你在你的域中使用它们,否则它们都不会,并且毕竟这会破坏使用DTO模式的目的。
DTO最适合façades,因为它们不一定与域绑定,因为它们只是简化域或任何其他层的接口(它将取决于façade实现) 。也就是说,DTO应该是从外墙输入和输出数据的最佳选择。
换句话说:您不应跨物理边界输出域对象,因为域对象可能包含太多可能浪费数据传输的信息,而且您可能会公开私有的数据到域并且不应该为整个域的消费者所知。
DTO发挥自己的作用,只将所需数据映射到实际域之上的图层。此外,有时域对象包含可以序列化/反序列化的无用数据并恢复整个对象的有效状态(它们可能与数据连接有一些关联:考虑与域上下文关联的Entity Framework或NHibernate代理或会话分别......这只是一个例子,还有很多其他的)。
答案 2 :(得分:1)
我对DTO的理解是它们在Android中具有与“parcelable”非常类似的角色(这也要求成员变量可以分配(本机类型或直接实现可分割的接口)。
当穿越过程边界(IPC)时使用Parcelable,而DTO是稍微宽泛的模式。 (用于IPC,客户端/服务器通信等)(以便解释'可分配的',以及DTO如何不同)
DTO看起来具有相同的层次结构,DTO中的所有内容都必须是可串行的(虽然看起来不需要像Android案例那样提示某些特定的界面)所以我会说所有3个都是DTO。只是比其他人更复杂。
值得一提的是,另一个优点是封装了 通过线路传输数据的序列化机制。通过 像这样封装序列化,DTO保持这种逻辑 超出其余代码
从您的链接
Parcelable -requires-您要在类中包含序列化代码。而DTO只是一个很好的做法(不要求我不认为)
(抱歉这么多的android比较,我希望比较/对比有帮助)