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

发布于 2024-11-26 04:59:24 字数 2065 浏览 1 评论 0 原文

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

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

然而,这几天我一直在思考这是不是一个好方法。我读到的关于该主题的最新文章是: 有趣的 JPA 模式博客

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

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

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

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

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

替代方案 3: 我公开了一个方法/操作 addUpdateBook(BookDTO bookDto)。 POJO BookDTO 看起来与 POJO Book 一样,但它没有字段 Categorycategory,而是有一个字段 LongcategoryId 。在实现中,我在保留 Book 之前检索给定 categoryIdCategory

  • 优点:不会让客户端感到困惑 缺点
  • (?):方法 getBook(Long bookId) 应该返回什么?应该吗 仅返回 BookDTO?然后还需要调用 操作getCategory(LongcategoryId)为了获得“整个 图书信息”。然后客户端需要将 书的本地域表示的不同部分。 与替代方案 1 相比,这对客户端来说会更复杂 边?
  • 缺点:我需要在保留这本书之前检索类别。我 我猜这意味着一些开销。
  • 缺点:被迫在客户端中使用 DTO 会使其处理物理细节,并使其与实际的域模型有些距离。我似乎忽略了拥有域模型并在业务层使用 JPA 的要点。

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

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

I am working on an Adobe Flex front-end with a Java back-end using JPA for persistence. The protocol I am using is remote objects (AMF) implemented with BlazeDS.

I started out with a service-facade and entity DAOs, but without any specific DTOs. The same POJOs, the domain objects, were passed in the service-facade as those used as DTOs passed to the Hibernate DAOs.

However, the latest few days I have been thinking whether this is a good approach or not. The latest article on the subject I read was this one:
Interesting JPA Pattern blog

The situation:
Say I have POJO Book with a unidirection ManyToOne relation with the POJO Category (i.e. each book may only be associated with one category, but the same category may be associated with many books). I see some alternatives:

Alternative 1:
I expose a method/operation addUpdateBook(Book book). In the implementation of this operation I add/update both the book and the referenced category. I mean, if the client submits a book having a category that doesn't exist from before, this would mean that the client implicitly may edit categories using the addUpdateBook operation.

  • the client is working directly with the domain model!
  • the entire category information will be sent when a new book is added
    even though a reference to the category would be sufficient

Alternative 2:
I expose a method/operation addUpdateBook(Book book,Long categoryId). In the implementation I retrieve the category for the given categoryId and replace the category given in the book POJO and then I persist the book. In other words, I ignore any category in the book object, I just look at the categoryId. This means that the client would need to use another operation in order to modify the category.

  • pro: the client can still work more or less on the domain model, but ...
  • con: ... it is confusing for the client that the category of the book
    object will be ignored
  • con: the entire category information of the book will be sent, even
    if the server never will read it
  • pro: it may be more clear when a separate operation should be used
    for category modifications
  • con: I need to retrieve the category before persisting the book. I
    guess this means some overhead.

Alternative 3:
I expose a method/operation addUpdateBook(BookDTO bookDto). The POJO BookDTO looks as the POJO Book, but instead of a field Category category it has a field Long categoryId. In the implementation I retrieve the Category for the given categoryId before I persist the Book.

  • pro: not confusing for the client
  • con(?): what should the method getBook(Long bookId) return? should it
    return only the BookDTO? Then it would be required to invoke also the
    operation getCategory(Long categoryId) in order to have "the entire
    book information". Then the client would need to set together the
    different parts to a local domain representation of the book.
    Compared to alternative 1 this would be more complex on the client
    side?
  • con: I need to retrieve the category before persisting the book. I
    guess this means some overhead.
  • con: being forced to use the DTOs in the client makes it deal with physical details thereby and makes it somewhat distant from the actual domain model. It seems like I am missing the point with having an domain model and using JPA in the business layer.

I guess (!) alternative 3 is the way you would design the operations in a SOA context. However, for me, it is not that important to be loosely-coupled between the client and server. My focus is not to provide multiple client-platform support.

Which alternative would you propose? Are there other better alternatives? Do you know any nice resources, such as code examples, which could help me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生来就爱笑 2024-12-03 04:59:24

我正在使用与“替代方案3”相关的东西。一开始,我开始使用域对象(可能也是因为我的经验 dataservices),过了一段时间我发现了太多问题,我已经切换到DTO了。所有发布服务仅公开 DTO(均针对输入/输出参数)。

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

a) 您需要破坏域对象封装(例如公开属性或公开私有构造函数)才能使用它们进行数据传输。否则,您将不得不编写自己的序列化/反序列化。

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

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

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

I'm using something related to "Alternative 3". In the beginning I've started to use domain objects (probably also because of my experience with dataservices), after a while I found too many problems and I've switched to DTO's. All the publing services are exposing only DTO's (both for input/output parameters).

Some of the problems that I've met during working directly with the domain objects and BlazeDS:

a)you need to break the domain objects encapsulation (like exposing properties, or exposing private constructors) in order to use them for data transfer. Otherwise you will have to write your own serialization/deserialization.

b)you need to use tricks in order to allow data conversion between client/server. For example, using strings instead of dates in order to prevent timezone difference. Or using strings instead of int/double. You can solve some of these issues by writing custom proxies, but I still think that it's easier to use strings instead of other data types.

c)most of the time you don't need all the data from the domain objects, and in order to deal with that you need to use various frameworks with support for data pagination/lazy instantiation on the client. This frameworks are introducing complexity, and I try to stay away from that.

The main disadvantage of using DTO is the amount of boiler code in order to do the conversion between the domain objects-DTOs...but I still prefer using them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文