12

虽然显然不是所有的场景都可以通过一个设计来涵盖,但现在普遍认为 ORM 类应该在表示层和业务层(本地或远程)之间来回传递,从而取代对数据传输对象的需求?据我所知,使用 ORM 类会带来不必要的急切加载、上下文管理问题和紧密耦合的问题,但也节省了大量时间并保持简单。现在是否有一种标准方法通常偏向于另一种(对于大多数情况)?

4

6 回答 6

4

这是一个非常有趣的问题,也是我过去两年一直在调查和试验的问题。

我认为这里真的没有正确或错误的答案。我不认为你可以简单地说我想要一个,因为通常你可能想要一个混合,这取决于你的客户是什么(网页、ws、机器和/或本地、远程)。

这里要记住的重要一点是每种产品的优缺点,并根据您的要求应用它。

例如:

  • 如果您使用的是 SEAM,那么您会希望避免使用高度分层的架构,因为您可以访问扩展的持久性上下文。没有这种支持的其他 Web 技术往往与预先准备好状态的 DTO 一起工作得更好。
  • 如果您要发送远程消息,导入的目的是使其保持轻薄,DTO 通常在此处比富域对象更好地工作。在这里,您可以透明地抑制任何 ORM 问题/行为。
  • DTO 模式的好处是可以保护您的客户免受域更改的影响。如果您的应用程序是 Web 服务,这一点尤其重要,拥有定义合同的域(实体)对象可能会在某些时候让您陷入困境。

通过将系统分层包装并仔细公开和保护它们,您可以为许多不同类型的客户端生成各种 API。

于 2009-07-06T10:04:54.077 回答
2

紧耦合?请解释。

对我来说,DTO 是一种反模式。EJB3 允许我们省略使用它们。您可以在将实体发送到客户端之前强制执行延迟初始化。

当然,如果您只需要将 30 个字段中的两个发送给客户,您只需发送它们即可。但是,如果在我当前的项目中一直是整个副本 - 尝试摆脱那个 DTO。我看不出有任何理由使用它们。您按照客户的要求将业务对象发送给客户。为什么要使用包装器?

于 2009-07-06T18:07:44.943 回答
1

我认为 DTO 的存在与 JPA/Hibernate缺陷有关。如果您总是可以透明地进行延迟初始化,那么您将永远不会使用它们。因此,使用 DTO 是我的域/工作空间总是丢失(到处重复)的合同。总结一下,你可以使用它们,但你必须讨厌它们 :)

于 2009-07-06T14:45:44.247 回答
1

我有几个反对在表示层使用实体的问题:

  • 锁定:这最终会在您的演示文稿和模型之间产生紧密的锁定。在大型项目中进行更改变得昂贵,甚至是不可能的。现代工具还没有出现。

  • 安全性:使用模型对象,您可以轻松地将各种数据库 ID 信息传输到您的网页。这是一个明显的安全问题。使用dto:s您可以通过非常简单的会话映射将这些隐藏在服务器上。

  • 需求差异:GUI 视图很少是模型对象的直接列表。更多的时候,他们是更多的东西,结合野兽,guish。GUI 的需求往往会潜入到您的模型中,从而掩盖它。

  • 速度:对于实体,每次读取/写入它们时都会处理每个字段。由于您将它们直接传递给表示层,因此您很难尝试优化您的 JPA 查询 - 几乎是不可能的。在未来的项目中,我肯定会回到直接 JDBC 访问——就像 myBatis 一样。从而消除ORM。

我也有反对的问题DTO:s

  • 额外的 DAO 代码。

考虑到的事情,我会投票支持dto:s所有项目,JPA也消除。所以,我的堆栈变成了这样:

  • myBatis 用于数据库访问
  • POJO 作为 DTO:s
  • 我的 DAO 服务的无状态 EJB。
  • 用于 GUI 后端的 StatefulEJB。
  • JSF 用于演示。
于 2012-01-06T14:39:40.723 回答
0

我同意最后一个“演讲者”为什么在 ejb3 中使用包装器?我们在没有 DTO 的情况下构建了一个非常复杂的系统,但使用了它可以找到的实体 (JPA)。这很干净...

于 2009-11-05T15:28:58.753 回答
0

如果 GUI 控制器将对象属性发送到表单而不是实体对象,那么仅使用实体就可以了。另一方面,如果使用实体并且这些实体具有多对一关系,那么如果实体管理器没有急切地获取实体,那么人们应该会看到一些令人讨厌的异常。

例如,当尝试填充 Spring MVC 的标签或其他 GUI 组件的类似结构时,可以观察到这种情况。

此外,DTO 是放置额外注释(例如验证注释或 JAXB 等)的好地方

于 2011-09-26T12:25:49.373 回答