Java 服务层和控制器:谁负责什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3885675/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 06:21:00  来源:igfitidea点击:

Service layer and controller: who takes care of what?

javaspringarchitecturebusiness-logic

提问by toomuchcs

In class we're now learning how to build up a Spring application, even though spring isn't directly involved, we learned how to make the interfaces for DAO and service layer objects.

在课堂上,我们现在正在学习如何构建 Spring 应用程序,即使不直接涉及 spring,我们也学习了如何为 DAO 和服务层对象制作接口。

Please correct me if I'm wrong: DAO layer is pretty abstract: it just contains the CRUD operations and is further used to read data.(ie: get all objects, get specific objects, etc)

如果我错了,请纠正我:DAO 层非常抽象:它只包含 CRUD 操作并进一步用于读取数据。(即:获取所有对象、获取特定对象等)

Service layer: contains services to create things, and delete things, this is where business logic should be.

服务层:包含创建事物和删除事物的服务,这应该是业务逻辑所在。

Now all of this makes sense in the service layer; except "updating" objects. Do you just put a "update" function that just saves the object in your database? Or do you need to define the logic there as well? This is where my confusion is as, my understanding is objects in Spring are just POJO's. Now then who validates the data?

现在所有这些在服务层都有意义;除了“更新”对象。您是否只是放置了一个“更新”函数来将对象保存在您的数据库中?或者您是否还需要在那里定义逻辑?这就是我的困惑所在,我的理解是 Spring 中的对象只是 POJO。那么谁来验证数据呢?

Let's say I have an Object "child" it has:Name, SurName, Gender, Photo, Birthdatefields. how would I name the services? Or would you just let the controller take care of validation, which doesn't seem right to me. On the other hand it wouldn't seem right either to delegate every setter that needs to be called to the service layer.

假设我有一个对象“子项”,它有:Name, SurName, Gender, Photo,Birthdate字段。我将如何命名这些服务?或者你会让控制器负责验证,这对我来说似乎不正确。另一方面,将每个需要调用的 setter 委托给服务层似乎也不正确。

So just basically: help me with how to define saving your objects via the service layer.

所以基本上:帮助我如何定义通过服务层保存您的对象。

采纳答案by matt b

If you wish to have controllers be able to persist changes to a Childobject, then traditionally you would have a method in the service named something like ChildService.update(Child newchild), which will handle calling the correct DAOs to persist the new version of this Child.

如果您希望控制器能够持久保存对Child对象的更改,那么传统上您将在服务中使用一个名为 之类的方法,该方法ChildService.update(Child newchild)将处理调用正确的 DAO 以持久保存此 Child 的新版本。

Controllers are free to ask the service for a Child, change the fields around (conceivably based on some user input) - a sane design would have the Controller doing some work with the Child POJO and then asking the Service to persist the change. The model POJO should know nothing about a controller, service, or DAO but just simply hold data as you suggest - certainly you would not want every call to setName()or setGender()to automatically result in a database update.

控制器可以自由地向服务请求子项,更改周围的字段(可以想象基于某些用户输入) - 一个理智的设计会让控制器与子 POJO 一起做一些工作,然后要求服务保持更改。模型 POJO 应该对控制器、服务或 DAO 一无所知,而只是按照您的建议简单地保存数据 - 当然您不希望每次调用setName()setGender()自动导致数据库更新。

Instead, the controller and/or service should acquire a Childobject, do whatever work it needs to the object in it's unit of work, and then ask a Service (and then the DAO) to persist the changes.

相反,控制器和/或服务应该获取一个Child对象,对它的工作单元中的对象执行它需要的任何工作,然后请求服务(然后是 DAO)来持久化更改。

Validation can take place in several layers - the Controller might want to validate any input from the web user, and the Service may want to validate that it has a valid Childobject before it persists it. It especially makes sense to have some level of validation in both layers in case you want to re-use this Service in other capacities - such as exposing a REST interface, a different front-end, etc.

验证可以在多个层中进行——控制器可能想要验证来自 Web 用户的任何输入,而服务可能想要Child在它持久化之前验证它是否具有有效的对象。如果您想在其他功能中重用此服务,则在两个层中进行一定程度的验证尤其有意义 - 例如公开 REST 接口、不同的前端等。

回答by Nathan Hughes

Generally a Spring service is transactional. Things go into a particular service method because they ought to be grouped together in the same transaction. If you want to retrieve an object from the database, twiddle it, and save the new version, the retrieval and save ought to be in the same service method. So your service methods are determined according to what you need the application to do for the user.

通常,Spring 服务是事务性的。事物进入特定的服务方法,因为它们应该在同一事务中组合在一起。如果你想从数据库中检索一个对象,旋转它,并保存新版本,检索和保存应该在同一个服务方法中。所以你的服务方式是根据你需要应用程序为用户做什么来决定的。

I try to restrict controllers to doing work related to validating http parameters, deciding what service method to call with what parameters, what to put in the httpsession or request, what view to redirect or forward to, or similar web-related stuff.

我试图限制控制器做与验证 http 参数相关的工作,决定用什么参数调用什么服务方法,在 httpsession 或请求中放入什么,重定向或转发到什么视图,或类似的 Web 相关的东西。

As far as validation goes: Validating input parameters in the controller is a good thing to make sure nobody can break your application with bogus inputs. Validation in the controller tends to be about making sure the inputs are syntactically ok (including detecting injection attacks) while service-level validation is about making sure the state of things in the database is what you expect it to be.

就验证而言:验证控制器中的输入参数是一件好事,可以确保没有人可以使用虚假输入破坏您的应用程序。控制器中的验证往往是为了确保输入在语法上是正确的(包括检测注入攻击),而服务级别验证是为了确保数据库中的事物状态符合您的预期。

So controllers contain web-framework infrastructure code, services contain application logic code.

所以控制器包含网络框架基础设施代码,服务包含应用程序逻辑代码。