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

Apache flex 在使用远程服务连接blazeds/java/jpa时,我应该在flex中使用DTO或域对象吗?,apache-flex,jpa,remoting,blazeds,dto,Apache Flex,Jpa,Remoting,Blazeds,Dto,我正在开发一个AdobeFlex前端和一个使用JPA实现持久性的Java后端。我使用的协议是用BlazeDS实现的远程对象(AMF) 我从服务外观和实体DAO开始,但没有任何特定的DTO。服务外观中传递的POJO(域对象)与传递给Hibernate DAO的DTO使用的POJO相同 然而,最近几天我一直在思考这是否是一个好办法。我读到的关于这个主题的最新文章是: 情况: 假设我有一本POJO书,它与POJO类别有单向的manytone关系(即,每本书可能只与一个类别关联,但同一类别可能与多本书

我正在开发一个AdobeFlex前端和一个使用JPA实现持久性的Java后端。我使用的协议是用BlazeDS实现的远程对象(AMF)

我从服务外观和实体DAO开始,但没有任何特定的DTO。服务外观中传递的POJO(域对象)与传递给Hibernate DAO的DTO使用的POJO相同

然而,最近几天我一直在思考这是否是一个好办法。我读到的关于这个主题的最新文章是:

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

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

  • 客户端正在直接使用域模型
  • 添加新书时,将发送整个类别信息 即使提及该类别就足够了
备选方案2: 我公开了一个方法/操作
addUpdateBook(BookBook,Long categoryId)
。在实现中,我检索给定的
categoryId
的类别,并替换书POJO中给定的类别,然后保存该书。换句话说,我忽略book对象中的任何类别,只查看
类别ID
。这意味着客户端需要使用另一个操作来修改类别

  • 赞成:客户端仍然可以或多或少地在域模型上工作,但是
  • 反对者:。。。对客户来说,这本书的类别令人困惑 对象将被忽略
  • 缺点:这本书的全部分类信息都会被发送,甚至 如果服务器永远不会读取它
  • 赞成:当应该使用单独的操作时,可能会更清楚 用于类别修改
  • 缺点:我需要在保存该书之前检索该类别。我 我猜这意味着一些开销
备选方案3: 我公开了一个方法/操作
addUpdateBook(BookDTO BookDTO)
。POJO
BookDTO
看起来像POJO
Book
,但它不是一个字段
类别
,而是一个字段
长类别ID
。在实现中,我先为给定的
类别id
检索
类别,然后再持久保存
书籍

  • 赞成:不会让客户感到困惑
  • con(?):方法
    getBook(longbookid)
    应该返回什么?应该吗 仅将
    书籍返回到
    ?然后还需要调用
    操作
    getCategory(Long categoryId)
    以获得“整个 图书信息”。然后客户端需要将 将不同的部分转换为书籍的本地域表示。 与备选方案1相比,这在客户机上更加复杂 一边
  • 缺点:我需要在保存该书之前检索该类别。我 我猜这意味着一些开销
  • 缺点:被迫在客户机中使用DTO会使它处理物理细节,从而使它与实际的域模型有些距离。似乎我没有抓住拥有一个域模型和在业务层中使用JPA的要点
我猜(!)备选方案3是在SOA环境中设计操作的方式。然而,对我来说,在客户机和服务器之间松散耦合并不重要。我的重点不是提供多客户端平台支持


您会建议哪种选择?还有其他更好的选择吗?你知道有什么好的资源,比如代码示例,可以帮助我吗?

我正在使用与“选择3”相关的东西。一开始,我开始使用域对象(可能也是因为我的经验),过了一段时间,我发现了太多的问题,于是我转向了DTO。所有的发布服务都只公开DTO(都用于输入/输出参数)

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

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

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

c) 大多数情况下,您不需要来自域对象的所有数据,为了处理这些数据,您需要在客户端使用支持数据分页/延迟实例化的各种框架。这种框架引入了复杂性,我尽量避免这种情况


使用DTO的主要缺点是,为了在域对象DTO之间进行转换,需要大量的锅炉代码……但我仍然更喜欢使用它们。

感谢您分享您的经验,Cornel。你提到的问题“C”是我直接理解的问题,“A”和“B”可能会在以后遇到:)。我想处理“C”的一种方法是接受在调用中检索大量额外数据,但只要这不会导致性能问题就可以了