为什么 Collections 类包含独立(静态)方法,而不是将它们添加到 List 接口?

2022-09-04 20:15:16

对于集合中所有将 List 作为其第一个参数的方法,为什么这些方法不只是 List 接口的一部分?

我的直觉是:给定一个List对象,该对象本身应该“知道”如何对自己执行诸如rotation(),shuffle()或reverse()之类的操作。但是,作为一名 Java 程序员,我必须检查 List 接口中的方法,以及 Collections 类中“那边”的静态方法,以确保我使用的是规范解决方案。

为什么将某些方法作为静态独立方法放在 Collections 类中,而不是添加到 List 接口中(因此可能由某些现有或可能的基类实现)?

我试图更好地理解Java集合框架背后的设计决策。

这里是否有一些引人注目的OO设计原则,我忽略了这一点?还是仅仅出于某种实际的性能原因而进行这种区分?


答案 1

关键是,给定合适的基元操作(删除,设置等),一堆更高级的操作(排序,洗牌,二进制搜索)可以实现一次,而不是由每个列表实现来实现。

实际上,java.util.Collections 就像 .NET的Enumerable类 - 充满了通用方法,可以处理任何集合,以便它们可以共享单个实现并避免重复。


答案 2

列表接口方法背后的理性

  1. List 接口是 Java 运行时的一个非常核心的部分,在推出自己的 List 实现时,要完全实现所有成员已经有点繁琐了。因此,添加与列表定义没有直接关系的额外方法有点无关紧要。如果在 List 实现上需要这些方法,为什么不对接口进行子类化,然后需要它们呢?
  2. 如果您要在版本1.3中出现并通过添加新的实用程序方法向List接口添加功能,那么您将打破该接口的所有过去实现者。
  3. 从域驱动设计的角度来看,集合中的实用工具方法不是列表的正常域的一部分。
  4. 关于 OO 设计原则,我认为区分应用程序 OO 设计和语言运行时 OO 设计非常重要。

Java的作者可能会做一些非常不同的事情,因为他们对API的使用多年有了后见之明和观点。也就是说,C# IList 接口与 Java 非常相似,而 C# 的作者确实有这种观点。