【问题标题】:JSF Service LayerJSF 服务层
【发布时间】:2012-10-12 06:15:07
【问题描述】:

我不确定我在 JSF 中使用 MVC 环境的方法是否是最好的方法。由于我试图充分利用 JSF,我想知道我的服务层(或模型,用 MVC 术语来说)应该如何“设计”。

我知道 View-Controller 比率应该是 1 比 1(排除了例外情况)。 现在我应该以什么方式设计我的服务层?我应该使用一项大服务(不这么认为)吗?如果不是,我应该根据什么拆分我的服务?

请注意,我的服务将从 Bean(MVC 术语中的控制器)调用,并且服务本身将在必要时使用 JPA 调用 DAO。

提前致谢

【问题讨论】:

    标签: java model-view-controller jsf service-layer


    【解决方案1】:

    服务层(业务模型)应围绕主要实体(数据模型)设计。例如。 UserService 代表UserProductService 代表ProductOrderService 代表Order,等等。您绝对不应该拥有一个庞大的服务类左右。这是极其紧密的耦合。

    对于服务层 API 本身,Java EE 6 提供 EJB 3.1 作为服务层 API。在黑暗的 J2EE 时代,很久以前,当 EJB 2.0 难以开发时,Spring 更多地被用作服务层 API。现在有些人仍在使用它,但由于 Java EE 6 已经整合了从 Spring 中学到的所有优秀经验,所以它变成了superfluous。请注意,EJB(和 JPA)在 Tomcat 等准系统 servlet 容器中不可用。您需要在其上安装例如 OpenEJB(或仅升级到 TomEE)。

    无论选择何种服务层 API,最好的办法是通过完全在服务层中执行业务工作来保持您的 JSF 支持 bean(动作)侦听器方法尽可能流畅。请注意,服务层本身应该有任何 JSF 依赖项。因此,服务层代码中javax.faces.* 的任何(内)直接导入都表明设计不佳。您应该将特定的代码行保留在支持 bean 中(通常是根据服务调用结果添加面孔消息的代码)。通过这种方式,服务层可重用于其他前端,例如 JAX-RS 甚至普通 servlet。

    您应该了解,Java EE 应用程序中服务层的主要优势是容器管理事务的可用性。对@Stateless EJB 的一个服务方法调用实际上算作单个数据库事务。因此,如果在服务方法调用调用的使用@PersistenceContext EntityManager 的任何DAO 操作之一期间发生异常,则将触发完成 回滚。这样,您最终会得到一个干净的 DB 状态而不是一个脏 DB 状态,因为例如第一个 DB 操作查询成功,但第二个没有。

    另见:

    【讨论】:

    • 所以.. 如果您将其与 DAO(以及为此,实体)进行比较,该服务的比率将为 1 比 1?您的其余解释是 100% 清楚的,我服务的目的已经可以(所以业务逻辑,没有 JPA 逻辑,没有 JSF 逻辑)。我将需要更多地研究正确的范围等等。再次感谢您:)
    • 不完全是 1:1。您可以在单个服务类中注入多个 DAO。取决于实体本身是否有任何子实体。
    • @BalusC 将一个休眠类声明为 JSF bean 是否很常见?例如,我有一个公司视图(它具有名称、地址、联系人等属性)。我遇到了问题,因为除了所有 Company 属性之外,我还有一个 List。它给了我一个错误,因为它是一个休眠类,它试图找到一个不存在的 List 类型的列。我能够通过使其瞬态来解决问题。但这是一个好习惯吗?
    • @Erick:查看“另请参阅”链接以获取在支持 bean 类中正确使用实体类和服务类的具体示例。
    • 您应该明白,Java EE 应用程序中服务层的主要优势是容器管理事务的可用性。我喜欢这个
    【解决方案2】:

    如果您的应用中的实体很少,那么服务和模型实体之间的 1:1 比例可能还不错。但如果是大应用,服务就太多了。

    服务的数量取决于您正在设计的应用的用例。一旦在分析阶段确定了它们,就必须根据它们的功能将它们分成几组。每组用例都是一个服务,每个用例都是该服务中的一个方法。每个服务可以管理多个模型实体(您必须在其中注入执行其功能所需的 DAO)。通常,服务的用例管理模型类图中相互关联的模型实体。服务可能遵循“最大内聚/最小耦合”的良好做法。

    DAO 与模型实体的比例为 1:1。每个 DAO 对其实体执行 CRUD 操作和查询。如果一个方法需要查询 2 个关联实体,根据业务概念放到更合适的 DAO 中。

    在 JSF 表示层中,我在页面和控制器之间没有 1:1 的比例,这将是太多的控制器。我将执行每个服务的用例所需的所有页面组合到一个控制器中。因此,控制器和服务之间的比例是 1:1,将每个服务注入到其页面执行其用例的控制器中。

    当然,这些是一般原则。您可能在应用程序中有一些特殊情况会破坏它们,但它们很少。

    您可能不会有太多的服务和控制器,但也不会太少,因为那样它们就会有太多的逻辑和字段。你必须达成妥协。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-13
      • 2011-09-29
      • 2012-05-11
      • 2015-02-21
      • 2016-05-04
      相关资源
      最近更新 更多