'. '

Dependencies

From APIDesign

Revision as of 16:53, 16 October 2009 by JaroslavTulach (Talk | contribs)
Jump to: navigation, search

Contents

Dependencies

Not many APIs can live alone, without support from other parts of the system. Every C library needs libc, every Java code needs some version of JDK. As each library, also APIs have own environment, which defines what needs to be available around to allow the API to function properly. Each user of such shared library needs to recreate proper environment, that means to satisfy its dependencies, before its API can be used. This implies, that the dependencies of a library form an important API of the shared library itself.

These dependencies may not even be visible in external signatures (more about that in TypesOfDependencies)! They may only be needed during the runtime, internally, still changing them constitutes an API change. Imagine, that users of your API are using your library in some version and it works fine with just plain JDK. Suddenly, in newer release, you decide to change the library internals and depend on some other library, for example Jakarta Commons. That immediately means every user, who migrates to new version of your library, needs to include a version of Jakarta Commons in own application as well. This may or may not be a problem, however this is quite an externally visible change.

As the Chapter 3 defines APIs as everything that is externally visible, it makes sense to include shared library dependencies into the family of various types of APIs. In spite the fact, that it is very hidden kind of API, it is in fact one of the highest level kind and the API that we deal with the most during our day to day work.

Specifying Dependencies

Dependencies are usually specified as set of pairs. First element in each pair contains unique identification of needed API and also some specification of the API versions. Depending on the actual module system, the dependencies may be equality, greater than or even specified as a range.

It is important to mention that dependencies are almost always simplification of the real environment required. People often say: my library needs Java version 1.3, or version 1.5, while in fact then may mean: my application needs class JNDI (introduce as part of Java 1.3). Or my application requires annotations (added in version 1.5). That is more precise, however such exact description of own's dependencies is very complex and verbose. Much easier to simplify each dependency to just one number (with some interpretation).

Equality

One can depend on exact certain version of other library. This is however very restricting. If there is a part of application that needs Java 1.3 and another that needs Java 1.5, will you run each part of the application in different VM?

Thus this kind of dependency is useful only for modules which can be used separately, but are built and deployed together.

Greater Than

For modules deployed individually one needs to allow certain freedom. The equality dependency is too restricting. Usually people use equal or greater than dependency. It is usually expected that if program runs on Java 1.3, it will also run (relatively) fine on Java 1.5.

This of course requires the vendor of the library to follow rules of BackwardCompatibility - e.g. really design and especially evolve the API well. However most people designing commonly used libraries understand this and thus we can mostly rely on >= dependencies.

Personal tools
buy