Java 实用程序类与服务

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

Java Utility Class vs. Service

javastaticserviceutility

提问by djunforgetable

What's the difference in Java between a utility class (a class with static methods) and a Service class (a class with public methods that provides a "service"). For example, one can argue that a cryptographic object (providing methods to encrypt, decrypt, hash or get a salt value) is a Service provider, but many group this functionality into a Utility class with static methods, like CryptoUtil.encrypt(...). I'm trying to figure out which way follows better "design". Thoughts?

Java 中的实用程序类(具有静态方法的类)和服务类(具有提供“服务”的公共方法的类)之间有什么区别。例如,有人可能会争辩说,一个加密对象(提供加密、解密、散列或获取盐值的方法)是一个服务提供者,但许多人将此功能分组为具有静态方法的实用程序类,如 CryptoUtil.encrypt(.. .) 我试图找出哪种方式遵循更好的“设计”。想法?

采纳答案by erickson

Different behaviors can be obtained by using different service objects. Static methods in a utility class can't be swapped out. This is extremely useful for testing, changing implementations, and other purposes.

使用不同的服务对象可以获得不同的行为。实用程序类中的静态方法不能换出。这对于测试、更改实现和其他目的非常有用。

For example, you mention a CryptoUtilwith an encryptmethod. It would extremely useful to have different objects that could support different encryption strategies, different message recipients, etc.

例如,您提到了CryptoUtil一个encrypt方法。拥有可以支持不同加密策略、不同消息接收者等的不同对象将非常有用。

回答by cletus

The difference is that service classes might have state. And by state I mean conversational state. Consider a notional ordering system.

不同之处在于服务类可能有状态。我所说的状态是指会话状态。考虑一个名义上的排序系统。

interface OrderSystem {
  void login(String username, String password);
  List<Item> search(String criteria);
  void order(Item item);
  void order(Item item, int quantity);
  void update(Item item, int quantity);
  void remove(Item item);
  void checkout();
  Map<Item, Integer> getCart();
  void logout();
}

Such a thing could be done with stateful session beans (as one example), although in that case authentication would probably be covered more traditional EJB mechanisms.

这样的事情可以用有状态的会话 bean 来完成(作为一个例子),尽管在这种情况下,身份验证可能会涵盖更传统的 EJB 机制。

The point here is that there is conversational state in that the results of one call affects subsequent calls. You could view static methods as a bunch of simple stateless services that execute locally.

这里的要点是存在会话状态,因为一次调用的结果会影响后续调用。您可以将静态方法视为一堆在本地执行的简单无状态服务。

A service has a much broader meaning that includes, but is not limited to, being:

服务具有更广泛的含义,包括但不限于:

  • stateful;
  • remote; and
  • implementation dependent (ie through an interface).
  • 有状态的;
  • 偏僻的; 和
  • 依赖于实现(即通过接口)。

Best practice I think is to simply use static methods as convenience methods (especially given Java's lack of extension methods). Services are much richer than that.

我认为最好的做法是简单地使用静态方法作为方便的方法(特别是考虑到 Java 缺乏扩展方法)。服务比这丰富得多。

回答by sleske

I think there are no hard and fast rules.

我认为没有硬性规定。

I typically use static methods for functionality that requires few parameters, and can be accomplished in a single method call. Example:

对于需要很少参数的功能,我通常使用静态方法,并且可以在单个方法调用中完成。例子:

  • calculate a hash value for a string
  • convert a date to standard representation
  • 计算字符串的哈希值
  • 将日期转换为标准表示

If a functionality requires many parameters, and if there are several related results being created, then it's more practical to have a classe that can accept the shared parameters in its constructor, with several methods that perform the actual action.

如果一个功能需要很多参数,并且如果有几个相关的结果被创建,那么在它的构造函数中拥有一个可以接受共享参数的类,以及执行实际操作的几个方法会更实用。

Typical example: A database connection, which you first connect, then use to do a query, then use to get the result...

典型示例:一个数据库连接,您首先连接,然后用于执行查询,然后用于获取结果...

回答by Bill K

I answered this question here somewhere before, but what I found was that it was very easy to change the behavior of a Service--to refactor it into multiple services--where it takes a pretty significant refactor if you use a static class.

我之前在这里回答过这个问题,但我发现更改服务的行为非常容易——将其重构为多个服务——如果使用静态类,则需要进行非常重要的重构。

If that is the only difference (and I believe it is), then it never makes any sense to use static classes.

如果这是唯一的区别(我相信是),那么使用静态类就没有任何意义。

Any time someone says "There will never ever ever be more than 1 of these", code for n of them.

任何时候有人说“永远不会有超过 1 个”,请为其中的 n 个编码。

回答by quant_dev

You cannot override static method, which can be a huge problem in case you'd like to implement your service in two different ways and switch between them. For this reason, I would limit the use of static utility classes to simple things which will "never" (for sufficiently long value of "never" :)) need to be done in more than one way.

您不能覆盖静态方法,如果您想以两种不同的方式实现服务并在它们之间切换,这可能是一个大问题。出于这个原因,我会将静态实用程序类的使用限制为简单的事情,这些事情“永远不会”(对于“从不”的足够长的值:))需要以不止一种方式完成。