API elaboration describes the extent to which a developer can and must extend the API in order to achieve some goal. This post describes how to measure the extent to which your API meets the needs of your customers in terms of elaboration.
For each goal that the user might attempt to accomplish with the API describe the extent to which the user can and must extend the classes exposed by the API. List the types that the users can use directly, the types that they need to extend and the new types that they need to create. Some tasks and goals can be accomplished by using the types provided by the API. Other tasks and goals might require that the user override some default behavior in a derived class to achieve the desired functionality. Still other tasks and goals might require that the user provide a completely new type that implements some given interface, for example.
In the System.IO namespace, one user goal might be to write code that appends a line of text to a text file. The user can accomplish this task using the StreamWriter class exposed by System.IO. There is no need to extend this class or implement an interface in order to be able to accomplish this task.
API elaboration can be defined in the following terms.
- If the API allows users to accomplish all of their goals only by using the types exposed by the API without requiring further elaboration, the API does not support elaboration and can only be used as-is.
- If the API allows users to accomplish all of their goals only by extending some of the types exposed by the API and providing their own implementation of custom behavior, the API supports elaboration only at the fine tune level.
- If the API allows users to accomplish all of their goals only by replacing or introducing whole new types, then the API supports elaboration only at the replace level.
Note that an API can provide support for elaboration at multiple points on the scale. It might, for example, provide a set of components that can be used as-is for most user goals but that can also be extended or even replaced for a different set of user goals. Given this, it is vital to ensure that the API is measured against the core set of tasks that the target user would be expected to accomplish.
Some users do not expect to have to extend existing functionality in order to achieve their goals. Forcing these users to extend existing functionality to meet their goals will likely cause problems for them when using the API. On the other hand, some users may not feel comfortable using an API unless they are able to extend the API, should the need arise. These users look for some amount of flexibility built into the API and want to be able to fine tune the types available if required. Like the penetrability dimension, API elaboration can be described in terms of both what the API supports and what developers require. While an API may not demand that users specialize a number of classes or override a number of methods in order to be able to do any useful work, it might also be important that it does not prevent some developers from doing so, should they so wish.
Also, note that there are two ways to measure API elaboration, namely in terms of what the API supports and what it demands. An API may support extensibility but not demand it and vice versa. The user experience with an API that supports but does not demand extensibility is likely to be very different to one that demands extensibility for all tasks.