实用程序类(具有静态方法的类)和服务类(具有提供“服务”的公共方法的类)之间的 Java 有什么区别。例如,有人可能会争辩说加密对象(提供加密、解密、散列或获取盐值的方法)是服务提供者,但许多人将此功能分组到具有静态方法的实用程序类中,例如 CryptoUtil.encrypt(.. .)。我试图弄清楚哪种方式遵循更好的“设计”。想法?
5 回答
使用不同的服务对象可以获得不同的行为。实用程序类中的静态方法不能被换出。这对于测试、更改实现和其他目的非常有用。
例如,你提到了CryptoUtil
一个encrypt
方法。拥有可以支持不同加密策略、不同消息接收者等的不同对象将非常有用。
不同之处在于服务类可能具有状态。我所说的状态是指会话状态。考虑一个名义排序系统。
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();
}
这样的事情可以用有状态的会话 bean 来完成(作为一个例子),尽管在这种情况下,身份验证可能会涵盖更传统的 EJB 机制。
这里的要点是存在会话状态,即一次调用的结果会影响后续调用。您可以将静态方法视为一组在本地执行的简单无状态服务。
服务具有更广泛的含义,包括但不限于:
- 有状态的;
- 偏僻的; 和
- 依赖于实现(即通过接口)。
我认为的最佳实践是简单地使用静态方法作为便利方法(特别是考虑到 Java 缺乏扩展方法)。服务比这丰富得多。
您不能覆盖静态方法,如果您想以两种不同的方式实现服务并在它们之间切换,这可能是一个大问题。出于这个原因,我会将静态实用程序类的使用限制为“从不”(对于“从不”的足够长的值 :))需要以多种方式完成的简单事情。
我认为没有硬性规定。
对于需要很少参数的功能,我通常使用静态方法,并且可以在单个方法调用中完成。例子:
- 计算字符串的哈希值
- 将日期转换为标准表示
如果一个功能需要很多参数,并且如果要创建多个相关结果,那么在其构造函数中拥有一个可以接受共享参数的类,以及执行实际操作的多个方法会更实用。
典型例子:一个数据库连接,你先连接,然后用来做查询,然后用来获取结果……
我之前在某个地方回答过这个问题,但我发现改变服务的行为非常容易——将其重构为多个服务——如果使用静态类,则需要进行相当大的重构。
如果这是唯一的区别(我相信是),那么使用静态类就没有任何意义。
任何时候有人说“永远不会超过 1 个”,为其中的 n 个编码。