JSF服务层
我不确定我在JSF中使用MVC环境的方法是否是最好的方法。 既然我正在试图从JSF中获得最大的收益,我想知道我的服务层(或者说模型,用MVC术语讲)应该如何devise。
我知道视图控制器的比例应该是1比1(例外排除)。 现在我应该以什么方式devise我的服务层? 我应该使用一个大服务(不这么认为)吗? 如果没有,基于我应该分割我的服务?
请注意,我的服务将从Bean(MVC中的控制器)中调用,服务本身将在必要时使用JPA调用DAO。
提前致谢
服务层(业务模型)应该围绕主体(数据模型)进行devise。 例如User
, Product
, Order
等。你绝对不应该有一个巨大的服务类别。 这是非常紧密的耦合。
对于服务层API本身,Java EE 6提供了EJB 3.1作为服务层API。 在黑暗的J2EE时代,很久以前当EJB 2.0开发出来的时候,Spring被更多地用作服务层API。 现在有些人还在使用它,但是由于Java EE 6已经融入了从Spring学到的所有好教训,所以它变得多余了 。 请注意,EJB(和JPA)在诸如Tomcat之类的准系统servlet容器中不可用。 你需要安装例如OpenEJB(或者只是升级到TomEE)。
无论服务层API如何select,通过完全在服务层执行业务工作,最好的办法就是尽可能保持JSF支持bean(操作)侦听器的方法。 请注意,服务层本身不应该有任何JSF依赖关系。 因此,任何(in)直接导入的服务层代码中的javax.faces.*
都表示devise不好。 你应该把特定的代码行保留在后台bean(通常是根据服务调用结果添加一个faces消息的代码)。 这样服务层就可以重用于其他的前端,比如JAX-RS甚至纯servlet。
您应该了解,Java EE应用程序中服务层的主要优势是容器pipe理事务的可用性。 一个@Stateless
EJB上的服务方法调用可以作为单个数据库事务进行有效计数。 因此,如果在使用由服务方法调用调用的@PersistenceContext EntityManager
进行的DAO操作之一中发生exception,则将触发完整的回滚。 这样你最终得到一个干净的数据库状态,而不是一个脏数据库状态,因为例如第一个数据库操作查询成功,但第二个没有。
也可以看看:
- 为实体创build主 – 细节页面,如何链接它们以及select哪个bean范围
- 什么时候使用Spring或者EJB3或者全部使用它们是必要的还是方便的?
- JSF控制器,服务和DAO
如果您的应用程序中只有很less的实体,则服务和模型实体之间的1:1比例可能并不差。 但是,如果它是一个大的应用程序,将会有太多的服务。
服务的数量取决于您正在devise的应用程序的使用情况。 一旦在分析阶段确定了它们,就必须根据它们的function将它们分成几组。 每个用例组都是一个Service,每个用例都是该服务的一个方法。 每个服务可以pipe理多个模型实体(你必须注入它需要执行其function的DAO)。 通常情况下,服务pipe理模型实体的用例在模型的类图中相互重叠。 服务可以遵循“最大内聚/最小耦合”的良好实践。
DAO和模型实体之间的比例是1:1。 每个DAO执行CRUD操作并查询其实体。 如果一个方法需要查询2个关系实体,则根据业务概念将其放入更合适的DAO。
在JSF表示层中,页面和控制器之间的比率既不是1:1,也不是太多的控制器。 我把所有需要执行每个服务的用例的页面分成一个控制器。 所以控制器和服务之间的比例是1:1,在控制器的页面执行其使用情况中注入每个服务。
当然,这些是一般原则。 你可能在应用程序中有一些特定的情况,但是他们很less。
你可能没有太多的服务和控制器,但也不会太less,因为那样他们就会有太多的逻辑和领域。 你必须达成妥协。