JSF 服务层

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

我知道视图控制器比率应该是1比1(排除例外情况)。现在,我应该以何种方式设计服务层?我应该使用一个大型服务(不要这么认为)?如果没有,我应该根据什么来拆分我的服务?

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

提前致谢


答案 1

服务层(业务模型)应围绕主实体(数据模型)进行设计。例如: for 、 for 、 for 等。你绝对不应该有一个巨大的服务类左右。这是极度紧密的耦合。UserServiceUserProductServiceProductOrderServiceOrder

至于服务层API本身,Java EE 6提供了EJB 3.1作为服务层API。在黑暗的J2EE时代,很久以前,当EJB 2.0开发起来很糟糕时,Spring更常被用作服务层API。现在有些人仍然使用它,但是由于Java EE 6已经吸收了从Spring学到的所有经验教训,它已经变得多余了。请注意,EJB(和 JPA)在准系统 servletcontainer(如 Tomcat)中不可用。例如,您需要在其上安装OpenEJB(或者只是升级到TomEE)。

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

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

另请参阅:


答案 2

如果应用中的实体很少,则服务和模型实体之间的 1:1 比例可能还不错。但如果它是一个大应用程序,就会有太多的服务。

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

DAO 和模型实体之间的比率为 1:1。每个 DAO 都对其实体执行 CRUD 操作和查询。如果一个方法需要查询 2 个关系实体,请根据业务概念将其放入更合适的 DAO 中。

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

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

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


推荐