Deprecation
Context
Parts of a system are accessed using
interfaces which are unsatisfactory: for example, the interfaces expose
information which should be encapsulated, or they are inconsistent and hard
to use. However, there is too much code using the interface to change the
interface and all code using it in one go, or else the code which uses the
interface is not under the control of the interface writer. It may not be
possible to be completely confident that a particular modification to the
interface is an improvement, until it has been tried out by a large group
of users of the API.
Problem
The obvious solution is to modify the interface, release a
new version, and force all clients of the interface to be modified
accordingly. However, this may impose an unacceptable burden on the
maintainers of those clients (whether or not they are the same
people/organisation who own the interface). Worse, if a modification turns
out to be a mistake -- which may be hard to tell without full knowledge of
how an interface is being used -- it might be necessary to undo a
modification, whereupon the double modification of the client code would be
extremely wasteful of effort.
Solution
Using all available information, design a modification to
the interface which is believed to be an improvement. Add any new elements
to the interface. Any elements which are not present in the modified
interface are not immediately removed, but are documented as ``Deprecated''
with pointers to alternative features which should be used instead. Users
of the interface are encouraged to provide feedback on any problems they
encountered using the new interface without deprecated features,
particularly if this led client developers to continue using a deprecated
interface element. The default procedure is that in each new release of the
interface the features which were already deprecated in the previous
release are removed; but feedback from users may provoke a rethink; for
example, a feature which the interface designers had thought was not useful
and had marked ``deprecated'' might turn out not to be redundant, in which
its ``deprecated'' tag could be removed in a subsequent release.
Consequences
If cases emerge where it is difficult to avoid using a
deprecated interface element, the element can be used and the reason for
the difficulty examined. It may be that adequate replacement features are
not in place. By deprecating the element rather than removing it we avoid
presenting the API user with the frustrating situation in which a problem
which was soluble using one version of the API becomes insoluble using a
later version.
This technique is useful where the existing structure is reasonably
sensible, but interfaces are poorly designed or too broad. It is harder to
use it in cases where the structure needs to be redefined in a way which is
visible to the user. In such a case facilities may have to be temporarily
duplicated using the old and the new structure, which depending on the
length of the deprecation period may be unacceptable.
Depending on the nature of the user community the deprecation may be
ignored. One way to tackle this would be to specify that a deprecated
interface element will be removed in a specific version.
Known uses
Emacs, Java JDK, internal Edinburgh Concurrency Workbench development...
Contributors
Perdita Stevens, Rob Pooley