数据传输对象(DTO)模式是否已经废弃?

12

在一个完整的 Java EE 应用程序中,如果它是集群的,那么 DTO 模式仍然是一个有效的选项吗?此应用程序使用 EJBs Hibernate 和 Struts 与 Spring 等。在这种情况下传输领域对象是否存在任何问题?

编辑:为了澄清我的问题,随着现代资源和 Java EE 改进的提高,有理由不使用领域对象吗?如果没有,那么 DTO 模式是否正在逐渐淡出,并且不应该在新应用程序中使用?

3个回答

22

“DTO模式”并未被弃用。是否应使用DTO模式取决于应用程序架构。例如,在开发Web服务(使用JAX-WS或JAX-RS)时,应通过Web方法发送DTO,以便C#或Python客户端应用程序可以使用它,并且您的Web方法不应返回具有Hibernate注释或其他业务逻辑的对象类,记住在其他语言中,实体将不会创建带有这些注释或其他业务逻辑。


根据您的评论,这取决于软件架构。例如,我正在开发一个SOA项目,我们在服务层和表示层使用DTO。更深入地说,我们甚至使用DTO来处理服务内部的数据库通信,我们只使用SP与DB通信,因此Hibernate或任何其他ORM工具无法在那里工作,我们可以使用Spring DAO,该框架也使用DTO。现在许多应用程序中都可以找到许多DTO模式。
更多有关此问题的信息:
- DTO,VO,POJO,JavaBeans之间的区别?(基本上,任何DTO都是POJO)。 - Core J2EE Patterns - Transfer Object 编辑2:另一个信息来源,由Martin Fowler解释了使用DTO设计的主要原因。

结论:DTO不是反模式。只有在需要从一个子系统传递数据到另一个子系统,并且它们没有默认或标准的通信方式时,才应使用DTO。


在这种情况下,我理解使用DTO的用途。您正在使用DTO发送结果。但是对于内部应用程序,DTO并不是很有用,对吗? - Thihara
根据你的第一个喜好,这是一种反模式,用于规避实体 bean 无法序列化的事实。使用 ORM,这个主要问题就不存在了。 - Thihara
@Thihara,你理解错了。从EJB的正式定义来看,现在它被认为是一种反模式。从第一个链接的最后几行可以看出:“对于很多人来说,DTO和VO是一样的......大多数情况下,它们遵循JavaBean的约定,因此也是JavaBean。而且所有的都是POJO。” - Luiggi Mendoza
不,我明白那部分。但是让我困扰的是,对于同一软件的子系统或模块,没有必要使用DTO进行数据传输。带有JPA或Hibernate注释的对象不会造成问题。而且,像Struts这样的框架在将数据传输到视图时不需要使用DTO,因为域模型(Hibernate对象)就可以胜任。 - Thihara
实际上,使用现代MVC框架可以轻松地将视图映射到域对象。但我明白你的担心。 - Thihara
显示剩余2条评论

2
一个模式是纯设计。没有“弃用”模式,但随着时间的推移(或过度使用),使用量会减少。
就个人而言,我不明白为什么不使用DTOs。
例如-在oVirt开源项目中,我们有代表虚拟化领域中业务逻辑实体的实体。
这些实体应该被Hibernate注释注释(实际上,它们今天已经是了,因为我们开始使用hibernate POCs),并作为DTOs,然后有干净的无注释对象将映射到它们(假设使用dozer框架)并由客户端使用
(我不喜欢在客户端代码中有不必要的注释),或者实体应该作为传递给客户端的客户端对象(值对象),我们应该有其他类作为DTO实体

以上方法的缺点是您可能会有两个平行的类图-一个用于DTO,另一个用于值对象(由客户端使用)-但是,在设计中,在许多情况下存在权衡之处。
您必须了解优缺点并选择最适合您的内容(在我们的情况下,由于客户端是GWT,因此对于我们来说,将两个类层次结构分开会更容易,一个是DTO /服务器端,也可以用更多的仅限服务器端注释进行注释,另一个发送到GWT客户端代码)。

前端不是GWT,我哪里暗示了呢?它是使用大量JavaScript和jQuery的JSP。是的,zaske,我的问题是是否有必要使用它们,因为现代对象模型是保存数据的方式。 - Thihara

2

这是Java EE中非常有用的一种模式。

我使用DTO将相关实体对象从EJB bean传输到UI层。实体对象在“一个交易”中从数据库中获取(参见TransactionAttributeType.REQUIRED),并存储在DTO对象中。DTO在UI层中被使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接