我正在开发一个带有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
。这意味着客户端需要使用其他操作才能修改类别。
备选方案3:
我公开了一个方法/操作addUpdateBook(BookDTO bookDto)
。 POJO BookDTO
看起来像POJO Book
,但它不是字段Category category
,而是字段Long categoryId
。在实现中,我在保留Category
之前检索给定categoryId
的{{1}}。
Book
应该返回什么?应该是
只返回getBook(Long bookId)
?然后它还需要调用
操作BookDTO
以便拥有“整个
预订信息“。然后客户需要整理
本书的本地域表示的不同部分。
与备选方案1相比,这在客户端上会更复杂
侧?我猜(!)替代3是您在SOA上下文中设计操作的方式。但是,对我来说,在客户端和服务器之间松散耦合并不重要。我的重点不是提供多个客户端平台支持。
您会提出哪种替代方案?还有其他更好的选择吗?您是否知道任何可以帮助我的好资源,例如代码示例?
答案 0 :(得分:2)
我正在使用与“备选方案3”相关的内容。一开始我开始使用域对象(可能也是因为我对dataservices的经验),过了一段时间我发现了太多问题而且我已经切换到DTO了。所有公开服务都只暴露DTO(都是输入/输出参数)。
直接使用域对象和BlazeDS时遇到的一些问题:
a)您需要打破域对象封装(如公开属性或公开私有构造函数)以便将它们用于数据传输。否则,您必须编写自己的序列化/反序列化。
b)您需要使用技巧才能在客户端/服务器之间进行数据转换。例如,using strings而不是日期,以防止时区差异。或者using strings而不是int / double。您可以通过编写自定义代理来解决其中的一些问题,但我仍然认为使用字符串而不是其他数据类型更容易。
c)大多数时候你不需要来自域对象的所有数据,并且为了处理你需要使用各种框架来支持客户端上的数据分页/延迟实例化。这个框架引入了复杂性,我试图远离那个。使用DTO的主要缺点是锅炉代码的数量,以便在域对象-DTO之间进行转换......但我仍然更喜欢使用它们。