Documentation

The Java™ Tutorials
Hide TOC
API Design设计
Trail: Collections
Lesson: Interoperability

API Design设计

In this short but important section, you'll learn a few simple guidelines that will allow your API to interoperate seamlessly with all other APIs that follow these guidelines. 在这个简短但重要的部分中,您将学习一些简单的指导原则,这些指导原则将允许您的API与遵循这些指导原则的所有其他API无缝地互操作。In essence, these rules define what it takes to be a good "citizen" in the world of collections.本质上,这些规则定义了在集合界成为一个好“公民”的条件。

Parameters参数

If your API contains a method that requires a collection on input, it is of paramount importance that you declare the relevant parameter type to be one of the collection interface types. 如果您的API包含一个需要在输入时进行集合的方法,那么将相关参数类型声明为集合接口类型之一至关重要。Never use an implementation type because this defeats the purpose of an interface-based Collections Framework, which is to allow collections to be manipulated without regard to implementation details.永远不要使用实现类型,因为这违背了基于接口的集合框架的目的,该框架允许在不考虑实现细节的情况下操纵集合。

Further, you should always use the least-specific type that makes sense. 此外,您应该始终使用最不特定的有意义的类型。For example, don't require a List or a Set if a Collection would do. 例如,如果Collection可以,则不需要ListSetIt's not that you should never require a List or a Set on input; it is correct to do so if a method depends on a property of one of these interfaces. 并不是说你永远都不需要输入ListSet;如果方法依赖于其中一个接口的属性,那么这样做是正确的。For example, many of the algorithms provided by the Java platform require a List on input because they depend on the fact that lists are ordered. 例如,Java平台提供的许多算法都需要输入List,因为它们取决于List的顺序。As a general rule, however, the best types to use on input are the most general: Collection and Map.不过,一般来说,输入时使用的最佳类型是最通用的: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. 这样做会失去Java 集合框架提供的所有好处

Return Values返回值

You can afford to be much more flexible with return values than with input parameters. 与输入参数相比,您可以更灵活地处理返回值。It's fine to return an object of any type that implements or extends one of the collection interfaces. 可以返回实现或扩展其中一个集合接口的任何类型的对象。This can be one of the interfaces or a special-purpose type that extends or implements one of these interfaces.这可以是其中一个接口,也可以是扩展或实现其中一个接口的特殊用途类型。

For example, one could imagine an image-processing package, called ImageList, that returned objects of a new class that implements List. 例如,可以想象一个名为ImageList的图像处理包,它返回一个实现List的新类的对象。In addition to the List operations, ImageList could support any application-specific operations that seemed desirable. 除了List操作之外,ImageList还可以支持任何看起来需要的特定于应用程序的操作。For example, it might provide an indexImage operation that returned an image containing thumbnail images of each graphic in the ImageList. 例如,它可能提供一个indexImage操作,返回一个包含ImageList中每个图形的缩略图的图像。It's critical to note that even if the API furnishes ImageList instances on output, it should accept arbitrary Collection (or perhaps List) instances on input.需要注意的是,即使API在输出时提供ImageList实例,它也应该在输入时接受任意Collection(或List)实例。

In one sense, return values should have the opposite behavior of input parameters: It's best to return the most specific applicable collection interface rather than the most general. 从某种意义上说,返回值应该具有与输入参数相反的行为:最好返回最具体的适用集合接口,而不是最通用的集合接口。For example, if you're sure that you'll always return a SortedMap, you should give the relevant method the return type of SortedMap rather than Map. 例如,如果确定始终返回SortedMap,则应为相关方法提供SortedMap的返回类型,而不是MapSortedMap instances are more time-consuming to build than ordinary Map instances and are also more powerful. SortedMap实例比普通Map实例更耗时,而且功能也更强大。Given that your module has already invested the time to build a SortedMap, it makes good sense to give the user access to its increased power. 鉴于您的模块已经投入了时间来构建SortedMap,让用户能够访问其增强的电源是很有意义的。Furthermore, the user will be able to pass the returned object to methods that demand a SortedMap, as well as those that accept any Map.此外,用户将能够将返回的对象传递给需要SortedMap的方法,以及接受任何Map的方法。

Legacy APIs遗留API

There are currently plenty of APIs out there that define their own ad hoc collection types. 目前有很多API定义自己的特殊集合类型。While this is unfortunate, it's a fact of life, given that there was no Collections Framework in the first two major releases of the Java platform. 虽然这很不幸,但这是事实,因为Java平台的前两个主要版本中没有集合框架。Suppose you own one of these APIs; here's what you can do about it.假设您拥有其中一个API;以下是你能做的。

If possible, retrofit your legacy collection type to implement one of the standard collection interfaces. 如果可能,请改装旧版收集类型,以实现其中一个标准收集接口。Then all the collections you return will interoperate smoothly with other collection-based APIs. 然后,您返回的所有集合将与其他基于集合的API顺利互操作。If this is impossible (for example, because one or more of the preexisting type signatures conflict with the standard collection interfaces), define an adapter class that wraps one of your legacy collections objects, allowing it to function as a standard collection. 如果这是不可能的(例如,因为一个或多个先前存在的类型签名与标准集合接口冲突),请定义一个适配器类,该类封装一个遗留集合对象,使其可以作为标准集合使用。(The Adapter class is an example of a custom implementation.)Adapter类是自定义实现的一个示例。)

Retrofit your API with new calls that follow the input guidelines to accept objects of a standard collection interface, if possible. 如果可能的话,使用遵循输入指南的新调用来更新API,以接受标准集合接口的对象。Such calls can coexist with the calls that take the legacy collection type. 此类调用可以与采用旧集合类型的调用共存。If this is impossible, provide a constructor or static factory for your legacy type that takes an object of one of the standard interfaces and returns a legacy collection containing the same elements (or mappings). 如果这是不可能的,请为遗留类型提供一个构造函数或静态工厂,它接受一个标准接口的对象,并返回包含相同元素(或映射)的遗留集合。Either of these approaches will allow users to pass arbitrary collections into your API.这两种方法都允许用户将任意集合传递到API中。


Previous page: Compatibility
Next page: End of Trail