API 设计

原文: https://docs.oracle.com/javase/tutorial/collections/interoperability/api-design.html

在这个简短但重要的部分中,您将学习一些简单的指导原则,使您的 API 能够与遵循这些指南的所有其他 API 无缝地互操作。从本质上讲,这些规则定义了在收藏世界中成为一个好的“公民”需要什么。

参数

如果您的 API 包含需要输入集合的方法,那么将相关参数类型声明为集合接口类型之一是至关重要的。 从不使用实现类型,因为这违背了基于接口的集合框架的目的,即允许在不考虑实现细节的情况下操纵集合。

此外,您应该始终使用最不具体的类型。例如,如果 Collection 可以,则不需要 ListSet 。这不是你不应该在输入上要求ListSet;如果方法依赖于其中一个接口的属性,则这样做是正确的。例如,Java 平台提供的许多算法都需要输入List,因为它们依赖于列表的排序事实。但是,作为一般规则,输入时使用的最佳类型是最常用的:CollectionMap


Caution: Never define your own ad hoc collection class and require objects of this class on input. By doing this, you’d lose all the benefits provided by the Java Collections Framework.


返回值

使用返回值比使用输入参数更灵活。返回实现或扩展其中一个集合接口的任何类型的对象都可以。这可以是接口之一,也可以是扩展或实现这些接口之一的专用类型。

例如,可以设想一个名为ImageList的图像处理包,它返回实现List的新类的对象。除了List操作之外,ImageList还可以支持任何特定于应用程序的操作。例如,它可能提供indexImage操作,该操作返回包含ImageList中每个图形的缩略图图像的图像。值得注意的是,即使 API 在输出上提供ImageList实例,它也应该接受输入上的任意Collection(或可能是List)实例。

从某种意义上说,返回值应该具有输入参数的相反行为:最好返回最具体的适用集合接口,而不是最常见的。例如,如果您确定始终返回SortedMap,则应该为相关方法提供SortedMap的返回类型而不是MapSortedMap实例构建比普通Map实例更耗时,并且功能更强大。鉴于您的模块已经投入时间来构建SortedMap,因此让用户访问其增加的功能是很有意义的。此外,用户将能够将返回的对象传递给需要SortedMap的方法,以及接受任何Map的方法。

旧版 API

目前有很多 API 可以定义自己的临时集合类型。虽然这很不幸,但鉴于 Java 平台的前两个主要版本中没有 Collections Framework,这是生活中的事实。假设您拥有其中一个 API;这是你能做些什么。

如果可能,请改进旧版集合类型以实现其中一个标准集合接口。然后,您返回的所有集合将与其他基于集合的 API 平滑地互操作。如果这是不可能的(例如,因为一个或多个预先存在的类型签名与标准集合接口冲突),请定义一个适配器类,它包装您的一个旧集合对象,允许它作为一个标准集合。 (Adapter类是 自定义实现 的一个例子。)

如果可能,使用遵循输入准则的新调用来改进 API,以接受标准集合接口的对象。此类调用可以与采用旧版集合类型的调用共存。如果这是不可能的,请为遗留类型提供构造器或静态工厂,该构造器或静态工厂接受其中一个标准接口的对象,并返回包含相同元素(或映射)的旧集合。这些方法中的任何一种都允许用户将任意集合传递到您的 API 中。