【问题标题】:How to properly use Struts ActionForms, Value Objects, and Entities?如何正确使用 Struts ActionForms、Value Objects 和 Entities?
【发布时间】:2010-09-15 02:12:56
【问题描述】:

我继承了一个使用 Struts、Spring 和 Hibernate 的大型 Java 应用程序。我每天处理的类和接口有:Struts Actions、Struts ActionForms、值对象、服务接口和实现、DAO 接口和实现以及实体。我很清楚其中大多数的方式和原因,除了我不确定 ActionForms、Value Objects 和 Entities 之间的职责是否正确分离。我还应该提到域模型(即所有实体)不包含太多(如果有的话)真实的业务逻辑。这本质上是一个 CRUD 应用程序,大部分真正的逻辑都在数据库中(糟糕!)。无论如何,我想知道几个不同的 Java 相关问题:

1) Entities 和 Value Objects (VOs) 之间似乎没有太大区别,并且当它们以任一方向通过服务层时,必须编写大量代码才能转换为另一个(Struts Actions仅与 VO 打交道,DAO 仅与实体打交道)。因此,VO 和实体似乎有些多余。为什么两者都有?

2) VO实体翻译代码应该去哪里?服务层、Entity、VO?

3) VO 直接放入 ActionForms 并直接绑定到 JSP 中的标签(例如 )。这是一个好习惯吗?如果不是,合适的设计是什么?

4) 不清楚如何正确处理值对象中的外键依赖关系。例如,某些 VO 有一个类型字段,在数据库术语中,它表示与类型表的外键关系。在 UI 中,这转换为一个下拉字段,允许用户选择类型,或者一个标签,仅显示类型的文本表示(取决于它是哪个屏幕)。现在,VO 是否应该具有类型 ID 的属性、类型的文本表示,或两者兼而有之?谁负责在两者之间进行翻译,什么时候?

5) VO 有一个字段作为其数据库 ID。我以为VO没有身份?这是怎么回事?

我希望这些问题足够笼统,足以引起普遍关注。在这种类型的架构中似乎总是会出现这种情况。

另外,我怀疑这个架构对于这个应用来说太重了,如果你有更好的建议,请继续。但我主要对上述问题的答案感兴趣,因为不同的架构是我目前无法进行的长期重构。

【问题讨论】:

    标签: java design-patterns architecture oop


    【解决方案1】:

    1。 考虑到 DAO - VO 转换;这是否有用取决于如何使用 Hibernate。如果整个 Web 请求处理在单个 Hibernate 会话中,则您实际上不需要单独的 VO。

    但是,如果您的 DAO 层打开会话以检索对象并在您完成使用 DAO 之前关闭会话,您可能会遇到集合和对其他对象的引用的问题。那些被延迟加载的可能性很大,这意味着在请求这些属性时仍然必须打开 Session。

    简而言之,在您开始放弃这些 VO 之前,请仔细检查您的数据库事务和会话边界。

    3。 至于在表单中使用 VO;如果 VO 很好地映射到 JSP,我会说为什么不呢?我要么对数据模型与它支持的过程如此紧密匹配印象深刻,要么对数据库尚未标准化(这可能会也可能不会在未来造成问题)有点怀疑。

    回到 1。如果您使用带有延迟加载和集合的 DAO,请记住数据库会话还必须包含 JSP 阶段,因为 DAO 将在该阶段被读取。

    1. 服务层必须具有知道要更改哪些数据库对象的功能,而 id 正是为此而设计的。服务层将不得不从数据库中检索 DAO 并将来自 VO 的字段写入 DAO 中,尽管它显然不需要用 VO 的 id 更新 DAO 的 id :)

      李>
    2. 您需要从请求中得到外键字段的 id。由于它来自客户端,您可能应该在业务逻辑中检查是否存在具有此类 id 的对象。

    根据 VO 是接受外来对象的 id 还是需要对象,您应该:

    • 设置id,或者
    • 使用服务层通过 id 将外来对象作为 VO 获取,然后 将其放入您的 VO,并使用服务层存储它

    您的业务层负责翻译,因为服务层只处理对象检索和存储。并且文本或 id 不是对象,而是对象的标识符。服务层可以 提供搜索工具,但它不应该需要上下文信息。

    如果我没看错你的问题,你的 VO 通过 id 引用数据库中的其他对象。在这种情况下,您输入 id。如果你从客户端得到一个字符串,你应该在业务层(使用服务层)查找它,并将找到的对象的 id 放在 VO 中。或者,如果没有找到 ID,则返回一个像样的错误消息。

    作为结束语;除非您知道自己在做什么,否则不要碰 DAO-VO。 Hibernate 是一个强大而复杂的工具,看似简单易用。你很容易犯错误,而且很难找到。客户和老板们似乎都不喜欢在过去可以工作的东西中引入错误。

    顺便说一句;我在 DAO-VO 方面的保守主义来自于修复由于 EJB2 到 Hibernate 转换中的类似问题而导致的问题。魔鬼在细节中,改变你处理数据层的方式是一个重大的重构,即使它看起来像小菜一碟。

    【讨论】:

      【解决方案2】:

      要回答您的最后一部分,请使用 Spring MVC 而不是 Struts。然后,您可以在所有层使用相同的域对象 - 绑定到表单参数的类也在 Hibernate 中使用,并包含真正的业务逻辑。

      例如,在我使用 Spring MVC 做的应用程序中,我有一个成员类。登录、注册、更改密码和编辑个人资料表单都绑定到这个类。该类还有一个休眠映射和一个很好的内部业务逻辑(例如,对于社交网络,一个“添加朋友”方法)。

      【讨论】:

      • 在大型项目中,不能只从 Struts 切换到 Spring MVC。这是一个重大的重构。我几乎需要做一些小的增量更改。
      【解决方案3】:

      1) 不需要单独的 VO 和实体:一些公司要求他们的项目采用这样的结构。它可能在不同的项目中有意义,因此它是强制性的(我只能猜测)

      2) 服务层:它是与DAO和Action层的自然分离,对吧?

      3) 只要在发送到 DAO 之前经过适当验证,值对象就会被绑定

      4) 服务层应该负责两者之间的转换。在加载和保存期间

      5)如果他们没有身份,那么你将如何防止重复?

      我希望这些简洁的答案有所帮助。稍后我会尝试回复并给出更长的答案。

      【讨论】:

        猜你喜欢
        • 2013-08-06
        • 2018-07-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 2019-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多