简体   繁体   English

关于服务等级的几个问题

[英]A Few Questions About Service Classes

I have been learning to use service classes as templates for creating and modifying the values of an object.我一直在学习使用服务类作为模板来创建和修改对象的值。

My questions are as follows:我的问题如下:

  1. What is the definition of a service class?服务类的定义是什么? The book I am learning from does not define them and I have had trouble finding a definition online.我正在学习的书没有定义它们,我在网上找不到定义。

  2. Why would we want to use a separate service class when all the methods can be written in one class?当所有方法都可以写在一个类中时,我们为什么要使用单独的服务类?

  3. Should all service classes follow the structure of:所有服务类别都应遵循以下结构:

Instance variables.实例变量。

Default and non-default constructors默认和非默认构造函数

Accessor and mutator methods访问器和修改器方法

toString method toString 方法

Equals method等于方法

Other help methods as required根据需要的其他帮助方法

Or can service classes serve as something other than as a template for objects?或者服务类可以作为对象模板以外的东西吗?

There is no hard definition for what you're asking about, only 'general practices' that people adhere to more or less, depending on the circumstance.对于您要询问的内容没有硬性定义,只有人们或多或少遵守的“一般做法”,具体取决于具体情况。

Typically, a 'service' class handles requests from a user of some sort, encapsulating business logic and persistence away from the action being taken.通常,“服务”类处理来自某种用户的请求,将业务逻辑和持久性封装在所采取的操作之外。

For instance, a user wants to buy an item.例如,用户想要购买商品。 The service class exposes some method buy(Item item) .服务类公开了一些方法buy(Item item) The service class was instantiated with some notion of who is taking the action.服务类被实例化了一些关于谁在采取行动的概念。 It does all the 'heavy lifting' of marking that the item is bought, of calling the class that handles the money transfer, of calling the class responsible for placing a 'receipt' in the user's data, etc.它完成了所有“繁重的工作”,包括标记商品被购买、调用处理汇款的类、调用负责在用户数据中放置“收据”的类等。

What it does not do is any of these things directly.不直接做任何这些事情。 It does not write to the database, but defers to the User , Item , Inventory and Receipt classes as needed, who all know how to persist their own information.它不会写入数据库,而是根据需要遵循UserItemInventoryReceipt类,它们都知道如何保存自己的信息。 (Or it talks to a database service that does this.) A 'service' class really glues together a lot of lower-level functionality. (或者它与执行此操作的数据库服务对话。)“服务”类确实将许多较低级别的功能粘合在一起。

The reason you do this in a service class is for code base structure.您在服务类中执行此操作的原因是代码库结构。 For instance, if you have an Item object, it might be modified by a sale, by an administrator reducing the price, by an employee marking it as missing, etc. You could put all these methods into one class, but then where do you go when you want to update the checkout process?例如,如果您有一个Item对象,它可能会通过销售、管理员降低价格、员工将其标记为缺失等进行修改。您可以将所有这些方法放在一个类中,但是您在哪里当您想更新结帐流程时去? It becomes painful.它变得痛苦。 Instead, you have different services: PurchaseService , InventoryManagementService , etc. The particular services are dependent on your use-case, and where it makes sense to logically divide things up: for instance, it can be by action category ('Purchase') or it could be by user type ('CustomerService', 'OwnerService', 'EmployeeService', etc.) in order to make things like handling different permissions easier.相反,您有不同的服务: PurchaseServiceInventoryManagementService等。特定的服务取决于您的用例,以及在逻辑上划分事物有意义的地方:例如,可以按操作类别(“购买”)或可以按用户类型(“CustomerService”、“OwnerService”、“EmployeeService”等),以便更轻松地处理不同的权限。

Further, there is no reason for the service class to care about the particulars of how or where the data is ultimately stored.此外,服务类没有理由关心数据最终存储方式或存储位置的细节。 It should be 'agnostic' to details about the database, or files, or what have you.它应该对有关数据库、文件或您拥有的东西的详细信息“不可知”。 It's really only manipulating the specific classes that actually have that responsibility.它实际上只是在操纵实际具有该责任的特定类。 Remember: each class should really only have a single domain of responsibility.请记住:每个类实际上应该只有一个责任域。 If a class talks to the database, it should not be doing 'business logic' of also calculating, for example, the tax owed on a purchase.如果一个类与数据库对话,它不应该做同样计算的“业务逻辑”,例如,购买所欠税款。

Note that the Java language in no way enforces any of these practices.请注意,Java语言绝不会强制执行任何这些做法。 They are just things that people do in order to provide additional structure and make their life easier.它们只是人们为了提供额外的结构并使他们的生活更轻松而做的事情。 The compiler does not care.编译器不在乎。

What you mean by 'template' is unclear, but the template you lay out is really a template for any class, and thus isn't constrained to this context.您所说的“模板”是什么意思尚不清楚,但是您布置的模板实际上是任何类的模板,因此不受此上下文的限制。

It used to be a popular practice to place behaviour methods not inside classes holding data, but in separate classes called services (sometimes also called managers or handlers).过去流行的做法是将行为方法不是放在保存数据的类中,而是放在称为服务(有时也称为管理器或处理程序)的单独类中。

The biggest problem with this approach is that it leads to procedural (not object-oriented) design as your domain classes are just bags with getters and setters and all the logic of your application is inside service classes.这种方法的最大问题是它会导致程序化(而非面向对象)设计,因为您的域类只是带有 getter 和 setter 的袋子,并且您的应用程序的所有逻辑都在服务类中。 More about the Anemic Domain Model anti-pattern .有关贫血域模型反模式的更多信息。

Please note that does not mean, you should not have service classes in your application at all.请注意,这并不意味着您的应用程序中根本不应该有服务类。 When they should be used is described in the provided link.提供的链接中描述了何时应该使用它们。

A service class can be thought of as a way of a client to interact with some functionality in the application.可以将服务类视为客户端与应用程序中的某些功能进行交互的一种方式。 The is typically public, with some business meaning.通常是公开的,具有一定的商业意义。 For example, a Employee class might have properties such as employeeId, firstName, lastName, address which should be declared as private.例如,Employee 类可能具有应声明为私有的属性,例如employeeId、firstName、lastName、address。 And then there should be accessor methods for those known as setters and getters.然后应该有那些称为 setter 和 getter 的访问器方法。 Now there should be an overriden hashcode and equals method to find equality between objects.现在应该有一个覆盖的 hashcode 和 equals 方法来查找对象之间的相等性。 There may or may not be any business rule in the service classes , depending on the design pattern you plan to use.服务类中可能有也可能没有任何业务规则,这取决于您计划使用的设计模式。 One should also override the toString method in this object.还应该覆盖此对象中的 toString 方法。 Helpers are advised to be written in separate helper classes.建议将助手编写在单独的助手类中。 A simple example could be a MVC pattern where you can think of Models as the service classes and Controller as the helper classes (though they are not exactly same).一个简单的示例可能是 MVC 模式,您可以将模型视为服务类,将控制器视为帮助类(尽管它们并不完全相同)。 For more information about the topics you can refer to the following links :有关主题的更多信息,您可以参考以下链接:

  1. getters and setters getter 和 setter
  2. Equals and HashCode 等于和哈希码

I know this is an old post, but I hope this helps you or others who come across it.我知道这是一篇旧帖子,但我希望这对您或遇到它的其他人有所帮助。

  1. What is the definition of a service class?服务类的定义是什么? The book I am learning from does not define them and I have had trouble finding a definition online.我正在学习的书没有定义它们,我在网上找不到定义。

Everyone's definition is either very specific or very general.每个人的定义要么很具体,要么很笼统。 I take the general definition of, "a service class separates your business logic from other classes that you want to be reusable throughout an app".我采用一般定义,“服务类将您的业务逻辑与您希望在整个应用程序中可重用的其他类分开”。

  1. Why would we want to use a separate service class when all the methods can be written in one class?当所有方法都可以写在一个类中时,我们为什么要使用单独的服务类?

Using the below as an example.使用下面的例子。 Say you're building a GUI.假设您正在构建一个 GUI。 You'll have,你会有,

  1. View class - creates your visuals for your gui.查看类 - 为您的 gui 创建视觉效果。
  2. Controller class - contains the methods and functions for interacting with the view.控制器类 - 包含与视图交互的方法和函数。 (passing objects to the view from the DAO and vice versa, but ideally the DAO should be replaced by a service class). (将对象从 DAO 传递到视图,反之亦然,但理想情况下,DAO 应该由服务类替换)。
  3. DAO class - handles the actual CRUD operations in a database (ideally light weight and little if any business logic). DAO 类 - 处理数据库中的实际 CRUD 操作(理想情况下是轻量级且几乎没有业务逻辑)。

Suppose your app needs to return a record.假设您的应用需要返回一条记录。 Your controller calls the Dao, gets the record and sends it to the view.您的控制器调用 Dao,获取记录并将其发送到视图。 Simple, until you need to do more with the record as part of a process, like getUser(), isUserActive(), sendAccountDisabledEmail(), updateUser(), removeUserAssignedProjects()...很简单,直到您需要将记录作为流程的一部分进行更多操作,例如 getUser()、isUserActive()、sendAccountDisabledEmail()、updateUser()、removeUserAssignedProjects()...

Where would you put that code?你会把那个代码放在哪里?

You wouldn't put it in the view, because of separation of concerns, other classes couldn't use the methods, readability and just plain tight coupling making changes harder.你不会把它放在视图中,因为关注点分离,其他类不能使用方法,可读性和简单的紧密耦合使得更改更加困难。 You can put it in the controller, but other classes wouldn't be able to reference those functions, and again, readability and tight coupling.您可以将它放在控制器中,但其他类将无法引用这些函数,同样,可读性和紧密耦合。 You could put it in your Dao, and it would allow other classes to make use of the Dao and those operations, but now anytime you need to change something internal to the Dao, you risk breaking the Dao, you will have a big class that may be too hard to read and what would you do if you want to reference another Dao?你可以把它放在你的 Dao 中,它会允许其他类使用 Dao 和那些操作,但是现在任何时候你需要改变 Dao 内部的东西,你就有破坏 Dao 的风险,你会有一个大类可能太难读了,如果你想引用另一个道,你会怎么做? At this point the Dao is doing too much.在这一点上,道做的太多了。

Ideally, you would create a "service" class that handles all business logic for a group of operations.理想情况下,您将创建一个“服务”类来处理一组操作的所有业务逻辑。 The benefit is you now have a place to call other classes (DAO's including other service classes) and have them interact with each other.好处是您现在可以调用其他类(DAO 包括其他服务类)并让它们相互交互。 Chances are you would refactor anyway to using "service" classes as your app grows and becomes harder to refactor without breaking other classes.随着应用程序的增长并且在不破坏其他类的情况下变得更难重构时,无论如何您都可能会重构为使用“服务”类。

I'm not saying everything needs a service or has to use a service, because sometimes you can just call the DAO directly for simple things, but it's just a lot easier to manage your app if you have a consistent class hierarchy with a service layer from the start (aka don't put business logic in your DAO or reference other DAO's in your DAO).我并不是说一切都需要服务或必须使用服务,因为有时您可以直接调用 DAO 来完成简单的事情,但如果您有一个与服务层一致的类层次结构,那么管理您的应用程序会容易得多从一开始(也就是不要将业务逻辑放在您的 DAO 中或在您的 DAO 中引用其他 DAO)。

Should all service classes follow the structure of:所有服务类别都应遵循以下结构:

Instance variables.实例变量。

Default and non-default constructors默认和非默认构造函数

Accessor and mutator methods访问器和修改器方法

toString method toString 方法

Equals method等于方法

Other help methods as required根据需要的其他帮助方法

Or can service classes serve as something other than as a template for objects?或者服务类可以作为对象模板以外的东西吗?

This is very broad and it really depends on what your trying to do.这是非常广泛的,它真的取决于你想做什么。 Services can be instantiated for an operation and discarded, or manage states through it's own methods or others classes.可以为操作实例化服务并丢弃,或者通过它自己的方法或其他类来管理状态。 The key being, as long as your class is "orchestrating" and not actually playing any tunes, then I'd feel comfortable accepting it as a service class.关键是,只要您的课程是“编排”并且实际上没有演奏任何曲调,那么我会很乐意接受它作为服务课程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM