JSF服务层

21

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

我知道视图-控制器比例应该为1:1(除非有例外)。那么我应该如何设计我的服务层?我应该使用一个大型服务(我认为不应该这样做)吗?如果不是,基于什么原因应该拆分我的服务?

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

提前感谢

2个回答

41
服务层(业务模型)应该围绕主要实体(数据模型)进行设计。例如,UserService 用于 UserProductService 用于 ProductOrderService 用于 Order,等等。绝对不应该有一个巨大的服务类。那是极端的紧耦合。
至于服务层 API 本身,Java EE 6 提供了 EJB 3.1 作为服务层 API。在黑暗的 J2EE 时代,很久以前,当使用 EJB 2.0 开发非常糟糕时,Spring 更经常被用作服务层 API。现在仍有一些人在使用它,但由于 Java EE 6 已经吸收了从 Spring 中学到的所有好的教训,因此它已变得多余。请注意,在裸骨的 servlet 容器(如 Tomcat)中无法使用 EJB(和 JPA)。您需要在其上安装 OpenEJB(或升级到 TomEE)。
无论选择哪种服务层API,最好让您的JSF后备bean(操作)监听器方法尽可能“流畅”,通过完全在服务层执行业务工作来实现。请注意,服务层本身不应有任何JSF依赖项。因此,服务层代码中的任何(直接或间接的)javax.faces.*导入都表示设计不良。您应该保留后台bean中的特定代码行(通常是根据服务调用结果添加面向用户界面消息的代码)。这样,服务层可重用于其他前端,例如JAX-RS甚至纯servlet。
您应该了解,在Java EE应用程序中,服务层的主要优势是容器管理的事务的可用性。对于@Stateless EJB上的一个服务方法调用,在效果上相当于单个DB事务。因此,如果在使用@PersistenceContext EntityManager调用的任何DAO操作中发生异常,那么将触发complete回滚。这样,您就可以得到干净的DB状态,而不是脏的DB状态,因为例如第一个DB操作查询成功,但第二个操作未能成功。
另见:

所以,如果将服务与DAO(和实体)进行比较,它的比率将为1比1?您解释的其余部分100%清晰,我的服务目的已经很好了(因此是业务逻辑,没有JPA逻辑,也没有JSF逻辑)。我还需要进一步研究正确的作用域等。再次感谢您 :) - Menno
1
你可以在单个服务类中注入多个DAO,具体取决于实体本身是否有任何子实体。 - BalusC
@BalusC,将一个Hibernate类声明为JSF bean是常见的吗?例如,我有一个公司视图(它具有名称、地址、联系方式等属性)。我遇到了一个问题,因为除了所有公司属性之外,我还有一个List<Company>。它给我一个错误,因为它是一个Hibernate类,它试图找到一个类型为List<Company>的列,但这种列不存在。我可以通过使其瞬态来解决问题。但这是一个好的做法吗? - Erick
@Erick:请查看“参见”链接,以获取实体类和服务类在后备bean类中正确使用的具体示例。 - BalusC
你应该明白,在Java EE应用程序中,服务层的主要优势是可用性容器管理的事务。我喜欢这个。 - 王奕然
@BalusC 那这个方案怎么样:EJB用于一些抽象的门面(服务层),CDI bean用于门面后面的控制器(业务层),实体用于模型(数据访问层)? - The Bitman

3
如果你的应用程序中实体数量较少,服务和模型实体之间的1:1比率可能不错。但如果是一个大型应用程序,则会有太多的服务。
服务的数量取决于您设计的应用程序的用例。一旦您在分析阶段确定了它们,您必须根据它们的功能将它们分组为几个组。每个用例组将是一个服务,每个用例将是该服务中的一个方法。每个服务可以管理多个模型实体(并且您必须注入它需要执行其功能的DAO)。通常,服务的用例管理模型类图中相互关联的模型实体。服务可能遵循“最大内聚/最小耦合”的良好实践。
DAO和模型实体之间的比率为1:1。每个DAO执行其实体的CRUD操作和查询。如果一个方法需要查询2个相关实体,请将其放在更适合的DAO中,具体取决于业务概念。
在JSF表示层中,我没有页面和控制器之间的1:1比率,那将会有太多的控制器。我将需要执行每个服务用例的所有页面分组到一个控制器中。因此,控制器和服务之间的比率为1:1,在其页面执行其用例的控制器中注入每个服务。
当然,这些是一般原则。您的应用程序中可能有一些特殊情况打破了它们,但这些情况很少。
你可能没有太多的服务和控制器,但也不要太少,否则它们将具有太多的逻辑和字段。你必须达到一个折衷。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接