我最近听到有人说数据传输对象(DTO)是一种反模式。
为什么?有哪些选择?
我最近听到有人说数据传输对象(DTO)是一种反模式。
为什么?有哪些选择?
Answers:
有些项目的所有数据都有两次。一次作为域对象,一次作为数据传输对象。
这种重复需要付出巨大的代价,因此该架构需要从这种分离中获得巨大的收益,才能使其值得。
DTO不是反模式。通过网络发送某些数据(例如,通过Ajax调用发送到网页)时,您要确保仅发送目标将使用的数据来节省带宽。同样,对于表示层来说,以与本机业务对象略有不同的格式存储数据通常很方便。
我知道这是一个面向Java的问题,但是在.NET语言中,匿名类型,序列化和LINQ允许即时构建DTO,从而减少了设置和使用它们的开销。
在EJB 3.0之前的EJB规范中,实体Bean具有很重的性质,导致使用了诸如数据传输对象(DTO)之类的设计模式。DTO成为了轻量级对象(首先应该是实体bean本身),用于跨层发送数据...现在EJB 3.0规范使Entity bean模型与普通旧Java对象(POJO)相同。使用这个新的POJO模型,您将不再需要为每个实体或一组实体创建DTO ...如果要跨层发送EJB 3.0实体,则使它们只需实现java.io.Serialiazable
我不认为DTO本身就是反模式,但是存在与DTO的使用相关的反模式。Bill Dudney以DTO爆炸为例:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
这里还提到了许多DTO滥用情况:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
它们起源于三层系统(通常使用EJB作为技术)作为在层之间传递数据的一种方式。基于诸如Spring之类的框架的大多数现代Java系统在另一层中采用了POJO作为域对象(通常用JPA等注释)的另一种简化视图。这里不需要使用DTO。
OO纯粹主义者会说DTO是反模式的,因为对象成为数据表的表示形式而不是真实域对象。
有些人认为DTO可能会滥用,因此是一种反模式。通常在不需要/不需要时使用它们。
本文模糊地描述了一些滥用行为。
问题不应该是“为什么”,而应该是“ 何时 ”。
最终,当仅使用它的结果是较高的成本(运行时或维护)时,它就是反模式。我从事的项目具有与数据库实体类相同的数百个DTO。每次您想要添加一个字段时,您的广告都会向IDTO添加四倍的ID-到DTO,到实体,从DTO到领域类或实体的转换,逆向转换... ...您忘记了获得的一些位置和数据不一致的。
当您确实需要域类的不同表示形式时,它不是反模式 -更平坦,更丰富,更狭窄,...
我个人是从域类开始的,并在正确的地方进行了适当的检查,并通过了它。我可以注释和/或添加一些“帮助程序”类,以进行映射,到数据库以及诸如JSON或XML的序列化格式……如果需要,我总是可以将一个类拆分为两个。
这是关于您的观点的-我更喜欢将域对象看作是扮演各种角色的单个对象,而不是彼此创建的多个对象。如果对象唯一的角色是传输数据,那么它就是DTO。