java JSF 服务层
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13011392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSF Service Layer
提问by Menno
I am not sure whether my approach with the MVC environment in JSF is the best way to go. Since I am trying to get the most out of JSF I would like to know how my Service Layer (or Model, speaking in MVC terms) should be 'designed'.
我不确定我在 JSF 中使用 MVC 环境的方法是否是最好的方法。由于我试图充分利用 JSF,我想知道我的服务层(或模型,用 MVC 术语来说)应该如何“设计”。
I know the View-Controller ratio should be 1 to 1 (exceptions ruled out). Now in what way should I design my Service Layer? Should I use one big service (don't think so)? If not, based on what should I split my services?
我知道 View-Controller 比率应该是 1 比 1(排除例外)。现在我应该以什么方式设计我的服务层?我应该使用一项大型服务吗(不这么认为)?如果没有,我应该根据什么来拆分我的服务?
Note, my Service will be called from the Beans (Controllers in MVC terms) and the Service itself will call DAO's using JPA when necessary.
请注意,我的服务将从 Bean(MVC 术语中的控制器)调用,并且服务本身将在必要时使用 JPA 调用 DAO。
Thanks in advance
提前致谢
回答by BalusC
The service layer (the business model) should be designed around the main entity (the data model). E.g. UserService
for User
, ProductService
for Product
, OrderService
for Order
, etc. You should absolutely not have one huge service class or so. That's extreme tight coupling.
服务层(业务模型)应该围绕主要实体(数据模型)进行设计。例如UserService
for User
、ProductService
for Product
、OrderService
forOrder
等。你绝对不应该有一个庞大的服务类。那是极度紧耦合。
As to the service layer API itself, Java EE 6 offers EJB 3.1 as service layer API. In the dark J2EE ages, long time ago when EJB 2.0 was terrible to develop with, Spring was more often been used as service layer API. Some still use it nowadays, but since Java EE 6 has incorporated all the nice lessons learnt from Spring, it has become superfluous. Note that EJB (and JPA) is not available in barebones servletcontainers such as Tomcat. You'd need to install for example OpenEJB on top of it (or just upgrade to TomEE).
对于服务层 API 本身,Java EE 6 提供了 EJB 3.1 作为服务层 API。在黑暗的 J2EE 时代,很久以前当 EJB 2.0 很难开发时,Spring 更常被用作服务层 API。现在有些人仍在使用它,但是由于 Java EE 6 已经整合了从 Spring 中学到的所有优秀课程,它已经变得多余了。请注意,EJB(和 JPA)在准系统 servlet 容器(例如 Tomcat)中不可用。你需要在它上面安装例如 OpenEJB(或者只是升级到 TomEE)。
Regardless of the service layer API choice, best would be to keep your JSF backing bean (action)listener methods as slick as possibleby performing the business job entirely in the service layer. Note that the service layer should by itself nothave any JSF dependencies. So any (in)direct imports of javax.faces.*
in the service layer code indicates bad design. You should keep the particular code lines in the backing bean (it's usually code which adds a faces message depending on the service call result). This way the service layer is reuseable for other front ends, such as JAX-RS or even plain servlets.
不管服务层 API 选择如何,最好的方法是通过完全在服务层中执行业务工作来使您的 JSF 支持 bean(操作)侦听器方法尽可能灵活。请注意,服务层本身不应具有任何 JSF 依赖项。因此javax.faces.*
,服务层代码中的任何(in)直接导入都表明设计不佳。您应该在支持 bean 中保留特定的代码行(它通常是根据服务调用结果添加人脸消息的代码)。通过这种方式,服务层可重用于其他前端,例如 JAX-RS 甚至普通 servlet。
You should understand that the main advantage of the service layer in a Java EE application is the availability of container managed transactions. One service method call on a @Stateless
EJB counts effectively as a single DB transaction. So if an exception occurs during one of any DAO operations using @PersistenceContext EntityManager
which is invoked by the service method call, then a completerollback will be triggered. This way you end up with a clean DB state instead of a dirty DB state because for example the first DB manipulation query succeeded, but the second not.
您应该了解 Java EE 应用程序中服务层的主要优势是容器管理事务的可用性。@Stateless
EJB上的一个服务方法调用有效地算作单个 DB 事务。因此,如果@PersistenceContext EntityManager
在服务方法调用使用的任何 DAO 操作之一期间发生异常,则将触发完整回滚。这样你最终会得到一个干净的数据库状态而不是一个脏的数据库状态,因为例如第一个数据库操作查询成功,但第二个没有。
See also:
也可以看看:
回答by choquero70
The 1:1 ratio between services and model entities maybe not bad if you have few entities in your app. But if it is a big app, there would be too much services.
如果您的应用程序中的实体很少,服务和模型实体之间的 1:1 比例可能还不错。但是如果是一个大的应用程序,就会有太多的服务。
The number of services depends upon the use cases of the app you are designing. Once you have identified them in the analysis phase, you must group them in several groups according to their functionality. Each group of use cases will be a Service, and each use case will be a method in that service. Each Service can manage several model entities (and you have to inject in it the DAOs it needs to perform its functionality). Usually the uses cases of a Service manage model entities inter-realationated in the class diagram of the model. The Services might follow the good practice of "max cohesion / min coupling".
服务的数量取决于您正在设计的应用程序的用例。一旦在分析阶段确定了它们,就必须根据它们的功能将它们分成几组。每组用例将是一个服务,每个用例将是该服务中的一个方法。每个服务可以管理多个模型实体(并且您必须在其中注入执行其功能所需的 DAO)。通常,服务的用例管理在模型的类图中相互关联的模型实体。服务可能遵循“最大内聚/最小耦合”的良好实践。
The ratio between DAOs and model entities is 1:1. Each DAO perform CRUD operations and queries of its entity. If a method needs to query 2 relationated entities, put it in the more suitable DAO depending on the business concepts.
DAO 和模型实体之间的比率是 1:1。每个 DAO 执行其实体的 CRUD 操作和查询。如果一个方法需要查询2个关联实体,根据业务概念将其放入更合适的DAO中。
In the JSF presentation layer I neither have a 1:1 ratio between pages and controllers, that would be too much controllers. I group into one contrller all the pages needed to perform the use cases of each service. So the ratio 1:1 is between controllers and services, injecting each service in the controller whose pages perform its use cases.
在 JSF 表示层中,我在页面和控制器之间没有 1:1 的比例,这将是太多的控制器。我将执行每个服务的用例所需的所有页面归为一个控制器。因此控制器和服务之间的比例为 1:1,将每个服务注入到其页面执行其用例的控制器中。
Of course, these are general principles. You may have some particular cases in the app that broke them, but they are few.
当然,这些都是一般原则。您可能会在应用程序中遇到一些破坏它们的特殊情况,但它们很少。
You might not have too much services and controllers, but not too few neither because then they would have too much logic and fields. You must acchieve a compromise.
你可能没有太多的服务和控制器,但也不能太少,因为那样它们会有太多的逻辑和字段。你必须达成妥协。