使用远程服务连接到blazeds / java / jpa时,我应该在flex中使用DTO或域对象吗?

时间:2011-07-24 22:33:41

标签: flex jpa remoting blazeds dto

我正在开发一个带有Java后端的Adobe Flex前端,使用JPA进行持久化。我使用的协议是使用BlazeDS实现的远程对象(AMF)。

我开始使用服务外观和实体DAO,但没有任何特定的DTO。相同的POJO(域对象)在service-facade中传递,就像传递给Hibernate DAO的DTO一样。

然而,最近几天我一直在考虑这是否是一个好方法。我读到的关于这个主题的最新文章是这样的: Interesting JPA Pattern blog

情况: 假设我有POJO Book与POJO ManyToOne具有单向Category关系(即每本书可能只与一个类别相关联,但同一类别可能与许多书籍相关联)。我看到了一些替代方案:

备选方案1: 我公开了一个方法/操作addUpdateBook(Book book)。在此操作的实现中,我添加/更新了书和引用的类别。我的意思是,如果客户端提交的书籍具有以前不存在的类别,这意味着客户端可以使用addUpdateBook操作隐式地编辑类别。

  • 客户端正在直接使用域模型!
  • 添加新书时将发送整个类别信息 即使对类别的引用就足够了

备选方案2: 我公开了一个方法/操作addUpdateBook(Book book,Long categoryId)。在实现中,我检索给定categoryId的类别并替换POJO书中给出的类别,然后我坚持使用该书。换句话说,我忽略了书籍对象中的任何类别,我只看categoryId。这意味着客户端需要使用其他操作才能修改类别。

  • pro:客户端仍然可以在域模型上或多或少地工作,但是......
  • con:...对于客户而言,这本书的类别令人困惑 对象将被忽略
  • con:甚至会发送图书的整个类别信息 如果服务器永远不会读它
  • pro:可能更清楚何时应该使用单独的操作 用于类别修改
  • con:我需要在保留本书之前检索该类别。一世 猜猜这意味着一些开销。

备选方案3: 我公开了一个方法/操作addUpdateBook(BookDTO bookDto)。 POJO BookDTO看起来像POJO Book,但它不是字段Category category,而是字段Long categoryId。在实现中,我在保留Category之前检索给定categoryId的{​​{1}}。

  • 亲:不要混淆客户
  • con(?):方法Book应该返回什么?应该是 只返回getBook(Long bookId)?然后它还需要调用 操作BookDTO以便拥有“整个 预订信息“。然后客户需要整理 本书的本地域表示的不同部分。 与备选方案1相比,这在客户端上会更复杂 侧?
  • con:我需要在保留本书之前检索该类别。一世 猜猜这意味着一些开销。
  • con:被迫在客户端使用DTO使得它处理物理细节,从而使它与实际的域模型有些距离。看起来我错过了拥有域模型并在业务层中使用JPA的观点。

我猜(!)替代3是您在SOA上下文中设计操作的方式。但是,对我来说,在客户端和服务器之间松散耦合并不重要。我的重点不是提供多个客户端平台支持。

您会提出哪种替代方案?还有其他更好的选择吗?您是否知道任何可以帮助我的好资源,例如代码示例?

1 个答案:

答案 0 :(得分:2)

我正在使用与“备选方案3”相关的内容。一开始我开始使用域对象(可能也是因为我对dataservices的经验),过了一段时间我发现了太多问题而且我已经切换到DTO了。所有公开服务都只暴露DTO(都是输入/输出参数)。

直接使用域对象和BlazeDS时遇到的一些问题:

a)您需要打破域对象封装(如公开属性或公开私有构造函数)以便将它们用于数据传输。否则,您必须编写自己的序列化/反序列化。

b)您需要使用技巧才能在客户端/服务器之间进行数据转换。例如,using strings而不是日期,以防止时区差异。或者using strings而不是int / double。您可以通过编写自定义代理来解决其中的一些问题,但我仍然认为使用字符串而不是其他数据类型更容易。

c)大多数时候你不需要来自域对象的所有数据,并且为了处理你需要使用各种框架来支持客户端上的数据分页/延迟实例化。这个框架引入了复杂性,我试图远离那个。

使用DTO的主要缺点是锅炉代码的数量,以便在域对象-DTO之间进行转换......但我仍然更喜欢使用它们。